redis

lobo · 2018-09-05 10:39:44 · 1991 次点击 · 预计阅读时间 2 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2018-09-05 10:39:44 的文章,其中的信息可能已经有所发展或是发生改变。

一、执行流程

每个客户端通过网络连接到redis时,redis将调用函数createClient()为该连接创建一个客户端结构体redisClient,以便保存该客户端的所有信息,该新连接即为业务连接,其主要用于客户端与redis之间的实际数据通信。Redis在createClient()函数中将为连接设置处理函数readQueryFromClient(),也即业务连接上有数据到来时将调用此函数进行处理。

1、redis接受客户端的连接

(1)、redis启动时将调用initServer()函数,调用函数anetTcpServer创建redis的监听socket,所有客户端对redis的网络连接都连接到该socket所监听的端口上;

(2)、调用函数aeCreateFileEvent设置监听socket的处理函数:acceptTcpHandler(),也就是当redis的监听socket收到数据(有新的连接到来)时将调用该函数进行处理;

(3)、lacceptTcpHandler()中将首先调用函数anetTcpAccept为新进来的业务连接创建一个业务socket;该业务socket后续将完成客户端与服务器之间所有的业务数据传输;然后通过函数acceptCommonHandler()调用createClient()为新连接创建一个客户端结构体redisClient.

(4)、在函数createClient()中,将调用函数aeCreateFileEvent设置该客户端的业务数据处理函数readQueryFromClient,即,当该客户端的业务socket中有数据到来了,则调用readQueryFromClient进行处理。

image.png

2、redis接受命令处理流程

(1)、客户端的请求数据由网络传递到redis的业务socket,redis将调用函数readQueryFromClient()读取数据到redisClient结构体的接收缓存querybuf中。

(2)、readQueryFromClient()将调用processInputBuffer()对该客户端输入缓存中的数据进行处理。

(3)、函数processInputBuffer()中,将首先解析收到的客户端数据,此解析过程将通过调用函数processInlineBuffer()或processMultibulkBuffer()完成,此过程将解析出客户端的命令名称,命令的参数个数以及具体参数值,redis有其自己定义的通信协议,只需按照此协议即可完成命令解析,其过程可参考本文最后的“附1. redis命令解析”。

(4)、函数processInputBuffer()中,命令解析完成之后将调用函数processCommand()完成命令处理过程。

(5)、将根据命令的名字查找相应的处理函数,命令的名字由前面的命令解析过程确定,命令查询操作将通过函数lookupCommand()完成,此函数将查找server的命令字典以快速找到对应的命令执行函数,查找到命令执行函数之后,还需调用call()函数来具体执行相应的“命令执行函数”。

image.png

二、 3.0集群

Redis 3.0集群采用了P2P的模式,完全去中心化。

1、redis有16384个hash槽;

2、每个node节点分管不同的hash槽;

3、集群中的所有信息(节点、端口、slot等),通过节点之间定期的数据交换而更新,PING-PONG机制;

Redis 3.0集群的工作流程如下图所示

image.png

三、哨兵机制

一个一主多从的Redis系统中,可以使用多个哨兵进行监控任务以保证系统足够稳健。此时,不仅哨兵会同时监控主数据库和从数据库,哨兵之间也会相互监控。并且使用奇数个哨兵。

Redis的哨兵(sentinel) 系统用于管理多个 Redis 服务器,该系统执行以下三个任务:

   (1)、监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常。

   (2)、提醒(Notification):当被监控的某个 Redis出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。

   (3)、自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移操作,它会将失效Master的其中一个Slave升级为新的Master, 并让失效Master的其他Slave改为复制新的Master; 当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用Master代替失效Master。

哨兵(sentinel) 是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossipprotocols)来接收关于Master是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master.

四、内部数据结构

1、 有序集合跳跃表实现 ???? https://blog.csdn.net/lz710117239/article/details/78408919

image.png

随机算法

    int zslRandomLevel(void) {

                 int level = 1;

                 while ((random()&0xFFFF) < (ZSKIPLIST_P * 0xFFFF))

                         level += 1;

              return (level<ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;

        }

该算法的核心条件:(random()&0xFFFF) < (ZSKIPLIST_P * 0xFFFF), random()&0xFFFF形成的数,均匀分布在区间[0,0xFFFF]上,那么这个数小于(ZSKIPLIST_P * 0xFFFF)的概率是ZSKIPLIST_P

redi运用场景小结:

1、string:

(1)、计数器运用、缓存

(2)、位操作(大数据处理),几亿用户系统的签到、在线状态

2、list:

(1)、最新N个数据的操作

(2)、消息队列

(3)、删除和过滤

(4)、分析分析,用于数据统计与防止垃圾邮件(结合set)

3、set

(1)、数据排重、统计

(2)、实时系统、发垃圾系统

(3)、共同好友、二度好友

(4)、求交集,实现好友推荐

4、hash

(1)、用户信息存储

5、Sorted Set:

(1)、排行榜,TOP N

(2)、设定精准过期时间、时间戳作为score

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1991 次点击  
加入收藏 微博
7 回复  |  直到 2019-12-07 21:51:59
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传