您的位置:首页 > 数据库 > Redis

Redis和MongoDB原理简析

2015-12-21 22:11 288 查看

1. Redis

1.1 NIO通信

因都在内存操作,所以逻辑的操作非常快,减少了CPU的切换开销,所以为单线程的模式(逻辑处理线程和主线程是一个)。

reactor模式,实现自己的多路复用NIO机制(epoll,select,kqueue等)

单线程处理多任务

1.2 数据结构

hash+bucket结构,当链表的长度过长时,会采取迁移的措施(扩展原来两倍的hash表,把数据迁移过去,expand+rehash)

1.3 存储

全量持久化(遍历redisDB,读取bucket中的key,value),save命令阻塞主线程,bgsave开启子进程进行snapshot持久化操作,生成rdb文件。

在shutdown时,会调用save操作

数据发生变化,在多少秒内触发一次bgsave

sync,master接受slave发出来的命令

增量持久化(aof),先写到日志buffer,再flush到日志文件中(flush的策略可以配置的,而已单条,也可以批量),

只有flush到文件上的,才真正返回客户端。

要定时对aof文件和rdb文件做合并操作(在快照过程中,变化的数据先写到aof buf中,等子进程完成快照<内存snapshot>后,再进行合并aofbuf变化的部分以及全镜像数据)。

2. MongoDB

2.1 通信

多线程方式,主线程监听新的连接,连接后,启动新的线程做数据的操作(IO切换),dispatch和io操作分析

以下是相关的线程

– interruptThread—只处理信号量。

– DataFileSync::run(后台)—调用MemoryMappedFile::flush方法将内存中的数据(脏页)刷到磁盘上。 我们知道,mongodb是调用mmap把磁盘中的数据映射到内存中的,所以必须有一个机制时刻的刷数据到硬盘才能保证可靠性,多久刷一次是与syncdelay参数相关的。

– FileAllocator::run—用于分配新文件,它决定分配文件的大小,例如用翻倍的方式。

– durThread–做批量提交和回滚工作。

– SnapshotThread::run—将生成快照文件帮助快速恢复

– ClientCursorMonitor::run—将管理用户的游标,每4秒调用一次idleTimeReport()方法,每一分钟调用sayMemoryStatus()方法

– PeriodicTask::Runner::run—将从动态数组std::vector PeriodicTask* _tasks中获取周期性任务执行

– TTLMonitor::run—理TTL,通过调用doTTLForDB()方法检查所有db。

– replSlaveThread—是当前结点作为secondary时的同步线程

– replMasterThread—是当前结点作为master时的同步线程。

– webServerThread

– 处理数据库请求的主线程

2.1 数据结构

数据库–>collection–>record

每一个数据库都有自己独立的文件。如果你开启了directoryperdb选项,那你每个库的文件会单独放在一个文件夹里。

数据库文件在内部会被切分成单个的块,每个块只保存一个名字空间的数据。在MongoDB中,名字空间用于区分不同的存储类别。比如每个collection有一个独立的名字空间,每个索引也有自己的名字空间。

在一个块中,会保存多条记录,每条记录是BSON格式的,记录与记录之间通过双向链表进行连接。

索引数据也存在数据文件中,不过索引是被组织成B Tree结构,而不是双向链表。

对每个数据库,有一个命名空间文件,用于保存每个名字空间对应的元数据。我们通过查询这些元数据来找到对应的名字空间的存储块位置。

如果你开启了jorunaling日志,那么还会有一些文件存储着你所有的操作记录

2.3 存储

MMap方式把文件地址映射到内存的地址空间,直接操作内存地址空间就可以操作文件,不用再调用write,read操作。

– DataFileSync::run(后台)—调用MemoryMappedFile::flush方法将内存中的数据(脏页)刷到磁盘上。 我们知道,mongodb是调用mmap把磁盘中的数据映射到内存中的,所以必须有一个机制时刻的刷数据到硬盘才能保证可靠性,多久刷一次是与syncdelay参数相关的。

journal(进行恢复用)是Mongodb中的redo log,而Oplog则是负责复制的binlog(对应Mysql)。

如果打开journal,那么即使断电也只会丢失100ms的数据,这对大多数应用来说都可以容忍了。从1.9.2+,mongodb都会默认打开journal功能,以确保数据安全。而且journal的刷新时间是可以改变的,2-300ms的范围,使用 –journalCommitInterval 命令。

Oplog和数据刷新到磁盘的时间是60s,对于复制来说,不用等到oplog刷新磁盘,在内存中就可以直接复制到Sencondary节点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mongodb redis