Redis运行机制与单线程

前言

当研究一个新组件之前我一般都会问几个问题,然后带着问题去研究。
当然,Redis is what,where to use,when to use,how to use这wwwh问题我默认你已经知道答案了。
我要问的问题是:
总听人说Redis是单线程的,是这么回事吗?为什么?
Redis内部都用到了哪些数据结构?存储这些数据结构的底层空间是怎么划分的?
Redis利用内存,它的垃圾回收机制是什么样的?
Redis支持事务和持久化吗?如果支持那么是怎么实现的?
Redis的主从,哨兵系统,集群如果有节点出了问题怎么处理?
别急,咱们一步一步来,本篇就先介绍一下Redis的单线程。

一、IO多路复用与Redis单线程

为什么要先抛出这个概念?因为这是海量客户端与redis进行命令交互的关口!
IO多路复用技术有很多种,包括select、epoll、kqueue、evport。redis底层会自动选择这四种中性能最高的技术作为与客户端IO交互的关口。
以select技术为例,系统底层维护了几个集合,这几个集合分别保存可读套接字、可写套接字、异常套接字等,内核会启动一个工作线程接收客户端的连接并把几种套接字分类放到对应的集合里。比如当前套接字为可读套接字,那么就把该套接字放到可读套接字集合。redis线程调用select函数的时候就会从上面的几个集合中获取套接字,获取到了就对套接字进行读写,获取不到可以阻塞等待也可以直接返回(一般是阻塞等待)。本质上是内核线程作为生产者往集合里生产套接字,redis用户线程作为消费者从集合里拿数据。

问题1、单线程体现在哪?

答:上面了解了redis线程从相关套接字集合中获取套接字,这个redis线程就是我们所谓的单线程。

问题2、这个单线程职责是啥?

答:redis单线程取到了相关套接字之后对其进行读写,这里以客户端发来set key value命令为例子,单线程读取到这个命令之后,对命令进行解析、查找命令表、调用命令对应的函数、写入数据库、返回写入结果给客户端。也就是说redis单线程除了负责读写套接字还负责执行命令的业务逻辑。除此之外redis单线程还负责调用垃圾回收函数进行垃圾回收。

问题3、单线程为啥还能这么快?

首先:多线程运行时需要上下文环境切换的,这些需要cpu的调度,线程多的时候浪费时间
然后:redis是纯内存操作,对内存的写入和读出都是非常迅速的,这也变相要求了我们在选择使用redis的时候尽量不要向redis里放大数据
然后:redis底层使用了一些特殊的数据结构如跳跃表等,通过这些数据结构的优化可以让对象更快的存入内存
最后:就是我们这里的IO多路复用技术了,底层封装了四种,选性能最优的执行

二、Redis数据库结构

redis底层实现实际上也是大量的对象、函数。只不过是用C而不是用Java。
redis的数据库就是一个对象redisDb,redis服务器对象redisServer内部会持有一个redisDb数组,初始的时候数组大小为16,即redis数据库最开始有16个,客户端存放的数据就在这16个中的一个。
我们知道redis是以键值对存储数据的,实际上redisDb内部保存了一字典dict,字典又保存了客户端的多个键值对,这个字典又被称为键空间。


image.png

读到这里你应该明白了,所有客户端存储在redis的数据都在redisServer对象的redisDb对象数组的某一个元素里面的dict下面
redisDb还有一个expires属性,这个属性也是一个字典,用与保存对象的过期时间

问题1、怎么进行数据增删改查?

了解hashmap的你一定知道,直接操作dict键空间就可以了。

三、Redis的垃圾回收机制

Redis回收过期对象的策略:定期删除+惰性删除

问题1、什么是定期删除?

答:定期删除就是每隔一定时间就进行一次删除,但与其他定期删除不同,redis定期删除并不会删除所有数据库中的所有过期对象。redis会检查某一些数据库(redisDb数组中的一些)中的某一些键,如果过期就删除,redis还会保存已经检查到了第几个数据库了,下次直接在该数据库开始检查。redis默认情况下每隔100ms执行一次定期删除,默认扫描16个数据库,每隔库检查20个键。

问题2、什么是惰性删除?

答:当客户端调用读写数据库的命令的时候,redis会判断这些命令涉及到的键是否过期,如果过期就删除。


惰性删除

问题3、为什么要两个组合删除?单独用一个不好吗?

答:只用定期删除全扫描会浪费cpu,惰性删除容易导致某些键扫描不到导致内存泄漏。两个组合起来刚好能覆盖整个内存。

问题4、Redis单线程是如何协调业务与垃圾回收的?

首先要了解redis服务器里两个事件
文件事件:redis处理客户端命令,套接字读写,键值对写入读取等
时间事件:redis内部垃圾回收事件,垃圾回收调用serverCron函数,需要定期执行
答:Redis单线程逻辑上先处理文件事件,后处理时间事件,实际执行的时间事件的时间可能略晚于时间事件所设定的时间,而且如果文件事件执行时间过长会break留到下次继续执行,把控制权交给时间事件。反之时间事件会调用子线程执行,让出控制权给文件事件。不会出现抢占等事件。
看下图,100ms执行一次时间事件,在85到130毫秒之间处理的是文件事件,时间事件被推迟到了131毫秒。从这个设计上可以看出redis对文件事件处理的优先级最高。
所以单线程只是对业务逻辑来说的,调用子线程证明用了其他线程了。


一次完整的事件处理

四、Redis持久化

redis持久化有两种
一种是内部调用SAVE/BGSAVE把redis数据库中的数据保存成RDB文件
一种是内部调用append sync等命令把客户端执行的命令保存成AOF文件

问题1、两种持久化有什么区别?

答:首先是保存的文件不同;然后是一个保存数据,一个保存产生数据的算法;最后是保存时机不同,RDB文件的时机用户可以通过save xxx时间内 yyy次修改 就调用BGSAVE保存,而AOF是在写入命令执行完成,返回之前把aof_buf缓冲区中的命令写入进入AOF文件的。

问题2、持久化操作不会浪费资源吗?

答:实际上BGSAVE命令执行的时候是Redis单线程又启动了一个线程,因此这里来看Redis也不是纯粹的单线程的。

总结

本篇博客我们介绍了redis单线程是怎么回事、redis的数据库结构、垃圾回收机制、持久化机制等。希望了解了这些概念的你能大体知道redis长什么样,由哪些东西组成的,这样以后再使用的时候就能够做到心中有数了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352