redis

lobo · · 1865 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

一、执行流程 每个客户端通过网络连接到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](https://static.studygolang.com/180905/44f4a849ad24df50f01ed34ce6835c5b.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](https://static.studygolang.com/180905/266fd16d499769c30d656f83dc3eb9db.png) 二、 3.0集群 Redis 3.0集群采用了P2P的模式,完全去中心化。 1、redis有16384个hash槽; 2、每个node节点分管不同的hash槽; 3、集群中的所有信息(节点、端口、slot等),通过节点之间定期的数据交换而更新,PING-PONG机制; Redis 3.0集群的工作流程如下图所示 ![image.png](https://static.studygolang.com/180905/d4c50f43ebb71f6b475ed4bb17dc7806.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](https://static.studygolang.com/180906/662f59f1a0cabc8ce66ebddea0d2518a.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

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