Redis
子知识库
文章
11 Sentinel
SentinelSentinel(哨兵)是Redis的高可用性解决方案,由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个master以及属下的所有slave。Sentinel在被监视的master下线后,自动将其属下的某个slave升级为新的master,然后由新的master继续处理命令请求。 1 Sentinel初始化过程启动并初始化Sentinel启动一个Sentinel可以使用命令: redis-sentinel sentinel.conf 或者 redis-server sentnel.conf —sentinel 当一个Sentinel启动时,会执行以下几步: 初始化服务器 将普通Redis服务器使用的代码替换成Sentinel专用代码 初始化Sentinel状态 根据配置文件,初始化监视的master列表 创建与master的网络连接 初始化服务器Sentinel本质上是一个运行在特殊模式下的Redis服务器,它的初始化过程与普通Redis服务器并不相同: 功能 Sentinel使用情况 数据库和键值对方面的命令:S...
12 集群与分片
集群分片0 概述Redis集群是分布式的数据库方案,通过分片(sharing)来进行数据共享,并提供复制或故障转移功能。 1 节点一个Redis集群通常由多个节点(node)组成。开始时每个node都是独立的,要将其连接起来: CLUSTER MEET 启动节点一个节点就是运行在集群模式下的Redis服务器,根据cluster-endabled配置选项是否为yes来决定是否开启集群模式。 节点在集群模式下会继续使用单机模式的组件,如: 文件事件处理器 时间事件处理器 使用数据库来保存键值对数据 RDB和AOF持久化 发布与订阅 复制模块 Lua脚本 节点会继续使用redisServer结构保存服务器的状态,redisClient结构保存客户端的状态,集群模式下的数据,保存在cluster.h/clusterNode、cluster.h/clusterLink、cluster.h/clusterState结构中。 集群数据结构cluster.h/clusterNode保存了一个节点的当前状态,如节点的创建时间、名字、配置纪元、IP和端口等。每个节点都有一个自己的clus...
13 发布与订阅
发布与订阅0 概述Redis的发布与订阅功能由PUBLISH、SUBSCRIBE、PSUBSCRIBE等命令组成。 通过执行SUBSCRIBE命令,客户端可以订阅一个或多个频道,成为这些频道的订阅者(subscriber):每当有其他客户端向被订阅的频道发送消息时,频道的所有订阅者都会收到这条消息。 客户端还可以通过PSUBSCRIBE订阅一个或多个模式:每当有其他客户端向某个频道发送消息,消息不仅会发送给这个频道的订阅者,还会发送给与这个频道相匹配的模式的订阅者。 1 频道的订阅与退订Redis将所有频道的订阅关系都保存在服务器状态的pubsub_channles字典中,键是某个被订阅的频道,值是一个链表,里面记录了所有订阅这个频道的客户端: 123struct redisServer { dict *pubsub_channels;}; 订阅频道每当客户端执行SUBSCRIBE命令时,服务器都会将客户端与被订阅的频道在pubsub_channles字典中关联: 如果频道已有其他订阅者,将当前客户端添加到订阅者链表的末尾。 如果频道未有订阅者,则在pu...
14 Redis使用场景
https://blog.csdn.net/zh15732621679/article/details/80614091 1 Redis使用场景计数器可以对 String 进行自增自减运算,从而实现计数器功能。 Redis 这种内存型数据库的读写性能非常高,很适合存储频繁读写的计数量。 缓存将热点数据放到内存中,设置内存的最大使用量以及淘汰策略来保证缓存的命中率。 查找表例如 DNS 记录就很适合使用 Redis 进行存储。 查找表和缓存类似,也是利用了 Redis 快速的查找特性。但是查找表的内容不能失效,而缓存的内容可以失效,因为缓存不作为可靠的数据来源。 消息队列List 是一个双向链表,可以通过 lpush 和 rpop 写入和读取消息 不过最好使用 Kafka、RabbitMQ等消息中间件。 会话缓存可以使用 Redis 来统一存储多台应用服务器的会话信息。 当应用服务器不再存储用户的会话信息,也就不再具有状态,一个用户可以请求任意一个应用服务器,从而更容易实现高可用性以及可伸缩性。 分布式锁实现在分布式场景下,无法使用单机环境下的锁来对多个节点上的进程进行同步。 ...
15 Redis缓存
1 缓存使用缓存步骤 前台请求,后台先从缓存中取数据,取到直接返回结果, 取不到时从数据库中取,数据库取到更新缓存,并返回结果, 数据库也没取到,那直接返回空结果 缓存预热缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据! 解决方法:1、直接写个缓存刷新页面,上线时手工操作下2、数据量不大,可以在项目启动的时候自动进行加载3、定时刷新缓存 缓存降级当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。 降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结算)。 在进行降级之前要对系统进行梳理,看看系统是不是可以丢卒保帅;从而梳理出哪些必须誓死保护,哪些可降级 2 Redis作为缓存可能会出现的问题缓存穿透问题:当有大量用户不走我们设置的键值,就会直接走数据库,就会给数据库造成极大的压力,导...
16 Redis消息队列
参考文献 redis做消息队列 1 List队列List 底层的实现就是一个「链表」,在头部和尾部操作元素,时间复杂度都是 O(1),这意味着它非常符合消息队列的模型。如果把 List 当作队列,你可以这么来用。 读非阻塞的消息队列 生产者使用 LPUSH 发布消息: 1234127.0.0.1:6379> LPUSH queue msg1(integer) 1127.0.0.1:6379> LPUSH queue msg2(integer) 2 消费者这一侧,使用 RPOP 拉取消息: 1234127.0.0.1:6379> RPOP queue"msg1"127.0.0.1:6379> RPOP queue"msg2" 但这里有个小问题,当队列中已经没有消息了,消费者在执行 RPOP 时,会返回 NULL。 12127.0.0.1:6379> RPOP queue(nil) // 没消息了 而我们在编写消费者逻辑时,一般是一个「死循环」,这个逻辑需要不断地从队列中拉取消...
20 Lua脚本
Redis从2.6版本开始引入对Lua脚本的支持,通过在服务器中嵌入Lua环境,Redis客户端可以使用Lua脚本,直接在服务器原子地执行多个Redis命令。 EVAL命令可以直接对输入的脚本进行求值: EVAL “return ‘hello world’” 0 “hello world” EVALSHA命令可以根据脚本的SHA1校验和来对脚本进行求值,但这个命令要求校验和对应的脚本至少被EVAL命令执行过一次,或者被SCRIPT LOAD命令载入过。 20.1 创建并修改Lua环境Redis服务器创建并修改Lua环境的整个过程有以下步骤: 创建一个基础的Lua环境 载入多个函数库到Lua环境 创建全局表格redis,表格包含了对Redis进行操作的函数,如redis.call 使用Redis自制的随机函数来替换Lua原有的带有副作用的随机函数 创建排序辅助函数 创建redis.pcall函数的错误报告辅助函数,这个函数可以提供更详细的出错信息 对Lua环境中的全局变量进行保护,防止用户在执行Lua脚本时添加额外的全局变量 将完成修改的Lua环境保存到服务器状态的lua属性...
21 排序
Redis的SORT命令可以对列表键、集合键或者有序集合键的值进行排序。 21.1 SORT <key>命令的实现SORT <key> 可以对一个包含数字值的键key进行排序,假设: PRUSH numbers 3 1 2 SORT numbers 创建一个和numbers长度相同的数组,每个元素都是一个redis.h/redisSortObject结构。 遍历数组,将每个元素的obj指针指向numbers列表的各个项,构成一一对应关系。 遍历数组,将各个obj指针所指向的列表项转换为一个double类型的浮点数,并将这个浮点数保存在相应数组项的u.score属性中。 根据数组项u.score的值,对数组进行数字值排序。 遍历数组,将各个数组项的obj指针所指向的列表项作为排序结果返回给客户端。 12345678910111213typedef struct _redisSortObject { // 被排序的值 robj *obj; // 权重 union { // 排序数字值时使用 ...
22 二进制数组
Redis提供了SETBIT、GETBIT、BITCOUNT、BITOP四个命令用于处理二进制位数组。 SETBIT,为位数组指定偏移量上的二进制位设置值0或1。 GETBIT,获取位数组指定偏移量上的二进制位的值。 BITCOUNT,统计位数组中1的个数。 BITOP,既可以对多个位数组进行按位与、按位或、按位异或运算,也可以对给定位数组取反。 22.1 位数组的表示Redis使用字符串来表示位数组,并使用SDS结构的操作函数来处理位数组。 redisObject.type的值为REDIS_STRING,表示字符串对象。 sdshdr.len值为1,表示这个SDS保存了一个一字节长的位数组。 buf数组的buf[0]字节保存了一个一字节长的位数组。 buf数组的buf[1]字节保存了SDS程序自动追加到值的末尾的’\0’。 22.2 GETBIT命令的实现 GETBIT 用于返回位数组bitarray在offset偏移量上的二进制位的值: 计算 byte = (offset / 8),byte记录了offset偏移量指定的二进制保存在位数组的哪个字节。 计算 ...
23 慢查询日志
Redis的慢查询日志,用于记录执行时间超过给定时长的命令请求,用户可以通过这个日志来监视和优化查询速度。 服务器有两个选项和慢查询有关: slowlog-log-slower-than,指定执行时间超过多少微妙的命令请求会被记录到日志上。 slowlog-max-len,指定服务器上最多保存多少条慢查询日志。数量超过,则先入先出。 SLOWLOG GET可以查看服务器保存的慢查询日志。 23.1 慢查询日志的保存123456789101112131415161718192021222324252627struct redisServer { // 下一条日志的ID long long slowlog_entry_id; // 保存了所有日志的链表 lisg *slowlog; long long slowlog_log_slower_than; unsigned long slowlog_max_len;};// slowlog链表保存了所有慢查询日志,每个节点都保存了一个slowlogEntry结构,代表一条日志...














