非阻塞虚存的几种实现选择
由于阻塞式虚存实现有各种缺点,因此,Redis实现了非阻塞式的虚存系统。实现非阻塞式虚存系统有以下几种方法:
- 最显然的方法,就是把整个redis做成多线程的,每个数据库操作都是自动分配到某个线程(或者fork一个新的线程),这样就不存在阻塞的问题。但是这对redis不是一个好的解决方案,因为为了实现提高操作速度,redis没有锁,保证原子性是通过顺序执行来保证的,因此整个redis引入多线程要增加锁,导致速度变慢(也许多核上能快点),并且极大增加代码量(现在redis只有1万行代码)。
- 通过非阻塞式IO实现,由于redis是基于事件循环的(event-loop based),可以采用非阻塞IO。但redis的作者基于以下两点把这个否了:①非阻塞文件操作不像sockets,会导致很多不兼容的问题,这和操作系统紧密相关,要做很多和操作系统相关的工作。②另外一个原因就是,在虚存中,文件IO操作仅仅是一部分,还有很多事件花在数据的编解码上面(编解码成交换文件swap file)。
- 于是就剩下最后一种方法,通过增加IO线程来完成数据交换。
下面,具体介绍第三种实现,即IO线程:
IO线程
IO线程的设计目标依重要性排列如下:
- 实现简单:尽量减少数据冲突(race)的可能性;用简单的锁;VM的代码要能够和Redis的其他代码分离(个人感觉这符合设计正交性原则)。
- 高性能,对于客户端访问数据不会造成锁(等待)。
- IO线程要能够编解码交换文件(针对第二种实现的缺点2)。
鉴于以上目标,Redis 的非阻塞VM实现的方式为,实现了一个redis主线程(实际和客户端交互的线程,处理请求),以及一些通过一个简单的信号量(mutex)和任务队列进行通信的IO进程。简单的说,主线程将IO请求交给IO线程进行后台处理(通过将一个(IO)任务结构交给server.io_newjobs队列)。假如没有IO进程,则新建一个。有些IO进程完成IO任务后,结果将发送到server.io_processed队列。IO进程将通过UNIX管道给主进程一个信号,以便告知已经完成,可以继续新的任务。
iojob的数据结构如下:
typedef struct iojob {
int type; /* Request type, REDIS_IOJOB_* */
redisDb *db;/* Redis database */
robj *key; /* This I/O request is about swapping this key */
robj *val; /* the value to swap for REDIS_IOREQ_*_SWAP, otherwise this
* field is populated by the I/O thread for REDIS_IOREQ_LOAD. */
off_t page; /* Swap page where to read/write the object */
off_t pages; /* Swap pages needed to save object. PREPARE_SWAP return val */
int canceled; /* True if this command was canceled by blocking side of VM */
pthread_t thread; /* ID of the thread processing this entry */
} iojob;
IO进程仅仅能处理三种类型的任务(通过上面的type域定义):
- REDIS_IOJOB_LOAD:将给定key的对象从交换空间load回主存。
- REDIS_IOJOB_PREPARE_SWAP:计算将val指向的对象交换到交换空间所需要的页数,计算的结果放在page域。
- REDIS_IOJOB_DO_SWAP:将val指向的对象交换到交换空间。
主线程除了以上三项工作不做以外,其他的工作都是主线程完成的,比如通过算法找到需要交换出去的对象之类的。
Comments (7)
为毛你推荐的广告是“第二代 让男人省事,让女人不省人事”。。。
感觉有必要把技术类blog和生活/评论类blog分开,这样有利于提高流量。至少要分到不同的tags下,方便分别订阅。
@grapeot
哈哈,肯定是百度更懂中国人,知道你的喜好~
话说google pagerank就和你博客的主题有关,要是大杂烩,pr值很低,并且google adsense匹配也不好,容易封号
现在我在这个博客基本不写生活类等不关痛痒的东西,否则好不容易搞来的订阅量又下去了(之前经常出现我没发一篇文章,订阅量瞬间降了几个,之后又慢慢升上来,现在基本不会了)
小炫耀一下,我的这个博客pr值已经是4是4是4啦
牛逼。。。4了。。。
我的意思不是生活类,而是大家都能看得懂或者受众面广的东西。这个redis的原理是不是太专业了?
查了一下哥的才2。。。主要的确没多少人链过去。。。
@grapeot
大家都能看懂的,大众的,肯定很多人写,权重就低了,哥现在主要还是要靠搜索引擎,权重很重要
只要我写过的,都得排前面才行,否则就白写了
(其实sigma很多人搜,我排名也比较前,但是没转化成流量,主要搜索出来的结果都是我这个博客的介绍,而不是介绍sigma这个词的文章)
有道理,如何选一个大家感兴趣但能写(或者能写得好看)的人又不多的领域就是学问了。这就是重要的东西。
@grapeot
嗯,感觉很多时候只能挖小的,之后慢慢积累,豆瓣就是这样发起来的