Redis理论基础

基本概念

数据类型

数据类型 数据结构 说明 适用场景
STRING 自己封装了一个sds的类型 能存储任何形式的字符串,包括:
1. 二进制数据
2. 序列化后的数据
3. JSON化的对象
4. 图片(Base64)
1. 普通的key/value存储
2. 保持计数(整数或浮点数自增或自减、访问超过阀值封锁)
3. 结合过期时间缓存Session
LIST 双向链表 1. 有序
2. 可重复
1. 缓存数据库表
2. 消息队列
3. 服务器的监控程序(在尽可能短的时间内,并行地检查一组网站,确保它们的可访问性)
SET value永远为null的HashMap(通过计算hash的方式来快速排重) 1. 无序
2. 不重复
3. string类型元素集合
1. 集合去重
2. 求交集
3. 求并集
4. 求差集
HASH Hash对应Value内部实际就是一个HashMap。
1. 成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应的value redisObject的encoding为zipmap。
2. 成员数量增大时会自动转成真正的HashMap,此时encoding为ht。
string类型的field和value的映射表 1. 购物车
2.高效率查询(hash的时间复杂度是O(1))
3. 存储对象
ZSET 使用HashMap和跳跃表(SkipList)来保证数据的存储和有序。
HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员。
排序依据是HashMap里存的score。
使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。
1. 有序
2. 不重复
3. string类型元素集合
4. 通过分数(score)进行排序
1. 以某个条件为权重排序
2. Top n排行榜

字符串实现原理

1
2
3
4
5
6
7
8
9
10
struct sdshdr{
// 记录buf数组中已经使用字节的数量(等于SDSN所保存字符串的长度)
int len;

// 记录buf数组中未使用字节的数量
int free;

// 字节数组,用于保存字符串
char buf[];
};

SDS数据类型的优点:

  1. 获取字符串长度变为O(1)。
  2. 线程安全,不会造成缓冲区溢出
  3. 减少了字符串改变造成的空间分配次数

持久化

对比项 RDB AOF
说明 在指定的时间间隔能对你的数据进行快照存储。 记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据。
安全性 较差 更安全
文件大小 较小 较大
恢复速度 较快 较慢

缓存淘汰策略

缓存淘汰策略 说明 适用场景
voltile-lru 从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰 希望一些数据能长期被保存,而一些数据可以被淘汰掉
volatile-random 从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰 希望一些数据能长期被保存,而一些数据可以被淘汰掉
volatile-ttl 从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰 需要通过设置不同的ttl来判断数据过期的先后顺序
allkeys-lru 从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰 1. 数据有一部分访问频率较高,其余部分访问频率较低
2. 无法预测数据的使用频率时
allkeys-random 从数据集(server.db[i].dict)中任意选择数据淘汰 所有数据访问概率大致相等
no-enviction 禁止驱逐数据,达到最大内存限制时, 如果需要更多内存, 直接返回错误信息。 数据量较少,有充足的内存

事务

介绍

功能/特点 说明
非严格的ACID事务 比如一串用EXEC提交执行的命令,在执行中服务器宕机,那么会有一部分命令执行了,剩下的没执行。
基本的命令打包执行的功能 在服务器不出问题的情况下,可以保证一连串的命令是顺序在一起执行的,中间有会有其它客户端命令插进来执行。
Watch 你可以对一个key进行Watch,然后再执行事务,在这过程中,如果这个Watched的值进行了修改,那么这个Transactions会发现并拒绝执行。

执行事务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
########### 执行事务 ##########
# 开启事务
$ multi

# 第一条命令进入等待队列
$ sadd 'user1' 2
# 第二条命令进入等待队列
$ sadd 'user2' 1

# 提交事务
$ exec

# 放弃事务
$ discard

基于watch机制实现乐观锁

监视一个(或多个)key,如果在事务exec执行之前这个(或这些)key被其它命令所改动,那么事务将被打断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
##########  ##########

# 设置k1的值为1
$ set k1 1

# 监视k1(客户端1执行)
# 当已经开始监视k1,则其它客户端不能修改k1的值
$ watch k1

# 开始事务(客户端1执行)
$ multi

# 设置k1的值为2(客户端2执行)
$ set k1 2

# 修改k1的值为3(客户端1执行)
$ set k1 3

# 提交事务(客户端1执行)
# k1值不会被修改为3,k1的值仍然是2,因为在事务开启之前k1的值被修改了
$ exec

发布订阅

说明
发布订阅 在Redis中,可以设定对某一个key值进行消息发布及消息订阅,当一个key值上进行了消息发布后,所有订阅它的客户端都会收到相应的消息。
适用场景 实时消息系统,比如普通的即时聊天,群聊等功能。

命令行实现发布订阅示例

配置Redis订阅端

1
2
3
4
5
# 订阅channel频道主题
$ subscribe channel
baidu
# 订阅匹配模式的主题(匹配以chan开头的频道主题)
$ subscribe chan*

配置Redis发布端

1
$ publish channel message

主从复制

介绍

说明
主从复制介绍 复制(replication)可以让其它服务器拥有一个不断更新的数据副本,从而使得拥有数据副本的服务器可以用于处理客户端发送的读请求。
主从复制用途 1. 从Redis主服务器向从服务器同步数据
2. 利用从库分担主库的读压力
主从复制同步触发时间 客户端每次向主服务器进行写入时,从服务器都会实时地得到更新。

工作原理

  1. 如果你为master配置了一个slave,不管这个slave是否是第一次连接上Master,它都会发送一个SYNC命令给master请求复制数据。
  2. master收到SYNC命令后,会在后台进行数据持久化,持久化期间,master会继续接收客户端的请求,它会把这些可能修改数据集的请求缓存在内存中。当持久化进行完毕以后,master会把这份数据集发送给slave,slave会把接收到的数据进行持久化,然后再加载到内存中。然后,master再将之前缓存在内存中的命令发送给slave。
  3. 当master与slave之间的连接由于某些原因而断开时,slave能够自动重连master,如果master收到了多个slave并发连接请求,它只会进行一次持久化,而不是一个连接一次,然后再把这一份持久化的数据发送给多个并发连接的slave。
  4. 当master和slave断开重连后,一般都会对整份数据进行复制。但从redis2.8版本开始,支持部分复制。

类型

复制类型 说明
全部复制 如果是全部复制的话,Master必须开启数据持久化功能,如果是降低开销关闭数据持久化,那也需要禁用master的自动重启功能,因为一旦master因为故障自动重启的话,主数据丢失,从节点会将空数据复制到从节点上,从而导致数据的丢失。
部分复制 主服务器会为复制流提供一个缓冲区,主从服务器都会维护一个复制偏移量和一个master run id,如果服务器断开,从服务器会向主服务器发送一个psync命令,并且将上次复制偏移量和run id发送给主服务器,主服务器验证run id和偏倚量,如果验证通过且偏移量相同,则继续从上次中断地方开始复制,如果验证不通过和偏移量不同,则选择全量同步。
无磁盘复制 主从复制主要是通过传输RDB文件到从服务器,从服务器加载RDB文件实现数据同步,但是文件的读取是很耗机器性能,所以从2.8.18开始尝试无磁盘复制,主要是将RDB文件直接传输到从服务器加载,不经过硬盘做中间的存储。

命令

1
2
3
4
5
6
7
8
9
# 查看replication状态
$ info replication

# 在从服务器上配置主服务器的ip、port
$ slaveof ip port

# 在主服务器失败的时候,将从属服务器用作新的主服务器,从而实现无间断运行。
# 注意:SLAVEOF NO ONE 不会丢弃同步所得数据集
$ slaveof no one

配置主从复制

环境说明

主机名 IP 操作系统
node1 192.168.100.101 CentOS7
node2 192.168.100.102 CentOS7
node3 192.168.100.103 CentOS7
node4 192.168.100.104 CentOS7

配置主服务器(node1)

1
2
3
# 设置密码
requirepass 123456
masterauth 123456

方法一:配置redis.conf(node2、node3、node4)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# 设置密码
requirepass 123456
masterauth 123456

# 配置主服务器的地址
slaveof 192.168.100.101 6379

# 配置从服务器只读
slave-read-only yes

########## 可选项 ##########

# 当slave丢失master或者同步正在进行时,如果发生对slave的服务请求,是否正常提供服务
# 可选项:
# yes:slave依然正常提供服务
# no:slave返回client错误:"SYNC with master in progress"
slave-serve-stale-data yes

# 是否使用无硬盘复制功能
# 默认值:no
# 可选项:
# yes:无磁盘复制(socket)
# no:磁盘复制(disk)
repl-diskless-sync no

# 无硬盘复制功能延迟时间
# 默认值:5
repl-diskless-sync-delay 5

# 从服务器发送PING命令给主服务器的周期(秒)
# 默认值:10
repl-ping-slave-period 10

# 设置主库批量数据传输时间或者ping回复时间间隔(秒)
# 默认值:60
repl-timeout 60

# 是否关闭无延迟同步
# 默认值:no,即采用无延迟同步
# 可选项
# no:则发送数据到 slave 端的延迟会降低,但将使用更多的带宽用于复制
# yes:Redis将使用一个较小的数字TCP数据包和更少的带宽将数据发送到slave,但是这可能导致数据发送到 slave 端会有延迟 , 如果是 Linux kernel 的默认配置,会达到 40 毫秒
repl-disable-tcp-nodelay no

# 设置主从复制容量大小,这个backlog 是一个用来在 slaves 被断开连接时存放 slave 数据的 buffer。
# 1、复制的后台日志越大, slave 断开连接及后来可能执行部分复制花的时间就越长。
# 2、后台日志在至少有一个 slave 连接时,仅仅分配一次。
repl-backlog-size 1mb

# 配置定义从最后一个 slave 断开连接后需要释放的时间(秒)。在 master 不再连接 slave 后,后台日志将被释放。
# 可选项:
# 0:不释放后台日志
repl-backlog-ttl 3600

# 作用:设置slave的优先级
# 1. 如果 master 不能再正常工作,那么会在多个 slave 中,选择优先值最小的一个 slave 提升为master
# 2. 优先值为 0 表示不能提升为 master 。
# 3. 数值越小,优先级越高
slave-priority 100

# 限制有N个以上从服务器才允许写入
# 最少包含的从服务器
min-slaves-to-write 3
# 延迟值
min-slaves-max-lag 10

方法二:启动时指定参数(node2、node3、node4)

1
$ ./redis-server --slaveof <master-ip> <master-port>

容灾处理

冷处理

当Master服务出现故障,需手动将slave中的一个提升为master,剩下的slave挂至新的master上

1
2
3
4
5
# 将从属服务器用作新的主服务器
$ slaveof no one

# 将slave挂至新的master上
$ slave of ip port

哨兵

功能

sentinel功能 说明
监控(Monitoring) Redis Sentinel实时监控主服务器和从服务器运行状态,并且实现自动切换。
提醒(Notification) 当被监控的某个 Redis 服务器出现问题时, Redis Sentinel 可以向系统管理员发送通知, 也可以通过 API 向其他程序发送通知。
自动故障转移(Automatic failover) 当一个主服务器不能正常工作时,Redis Sentinel 可以将一个从服务器升级为主服务器, 并对其他从服务器进行配置,让它们使用新的主服务器。当应用程序连接Redis 服务器时, Redis Sentinel会告之新的主服务器地址和端口。

流程

  1. Sentinel会监视一系列主服务器以及这些主服务器的从服务器,通过向主服务器发送PUBLISH命令和SUBSCRIBE命令,并向主服务器发送PING命令,各个Sentinel进程可以自主识别可用的从服务器和其它Sentinel。
  2. 当主服务器失效的时候,监视这个主服务器的所有Sentinel就会基于彼此共有的信息选出一个Sentinel,并从现有的从服务器当中选出一个新的主服务器。
  3. 当被选中的从服务器转换成主服务器之后,那个被选中的Sentinel就会让剩余的其它从服务器去复制这个新的主服务器(在默认设置下,Sentinel会一个接一个地迁移从服务器,但这个数量可以通过配置选项进行修改。)

命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# sentinel的基本状态信息
$ info sentinel

# 列出所有被监视的主服务器,以及这些主服务器的当前状态
$ SENTINEL masters

# 列出给定主服务器的所有从服务器,以及这些从服务器的当前状态
$ SENTINEL slaves <master name>

# 返回给定名字的主服务器的 IP 地址和端口号
$ SENTINEL get-master-addr-by-name <master name>

# 重置所有名字和给定模式 pattern 相匹配的主服务器。重置操作清除主服务器目前的所有状态, 包括正在执行中的故障转移, 并移除目前已经发现和关联的, 主服务器的所有从服务器和 Sentinel 。
$ SENTINEL reset <pattern>

# 当主服务器失效时, 在不询问其他 Sentinel 意见的情况下, 强制开始一次自动故障迁移,但是它会给其他sentinel发送一个最新的配置,其他sentinel会根据这个配置进行更新
$ SENTINEL failover <master name>

哨兵配置参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 哨兵sentinel实例运行的端口,默认26379  
port 26379
# 哨兵sentinel的工作目录
dir ./

# 哨兵sentinel监控的redis主节点的
## ip:主机ip地址
## port:哨兵端口号
## master-name:可以自己命名的主节点名字(只能由字母A-z、数字0-9 、这三个字符".-_"组成。)
## quorum:当这些quorum个数sentinel哨兵认为master主节点失联 那么这时 客观上认为主节点失联了
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 127.0.0.1 6379 2

# 当在Redis实例中开启了requirepass <foobared>,所有连接Redis实例的客户端都要提供密码。
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster 123456

# 指定主节点应答哨兵sentinel的最大时间间隔,超过这个时间,哨兵主观上认为主节点下线,默认30秒
# sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds mymaster 30000

# 指定了在发生failover主备切换时,最多可以有多少个slave同时对新的master进行同步。这个数字越小,完成failover所需的时间就越长;反之,但是如果这个数字越大,就意味着越多的slave因为replication而不可用。可以通过将这个值设为1,来保证每次只有一个slave,处于不能处理命令请求的状态。
# sentinel parallel-syncs <master-name> <numslaves>
sentinel parallel-syncs mymaster 1

# 故障转移的超时时间failover-timeout,默认三分钟,可以用在以下这些方面:
## 1. 同一个sentinel对同一个master两次failover之间的间隔时间。
## 2. 当一个slave从一个错误的master那里同步数据时开始,直到slave被纠正为从正确的master那里同步数据时结束。
## 3. 当想要取消一个正在进行的failover时所需要的时间。
## 4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来同步数据了
# sentinel failover-timeout <master-name> <milliseconds>
sentinel failover-timeout mymaster 180000

# 当sentinel有任何警告级别的事件发生时(比如说redis实例的主观失效和客观失效等等),将会去调用这个脚本。一个脚本的最大执行时间为60s,如果超过这个时间,脚本将会被一个SIGKILL信号终止,之后重新执行。
# 对于脚本的运行结果有以下规则:
## 1. 若脚本执行后返回1,那么该脚本稍后将会被再次执行,重复次数目前默认为10。
## 2. 若脚本执行后返回2,或者比2更高的一个返回值,脚本将不会重复执行。
## 3. 如果脚本在执行过程中由于收到系统中断信号被终止了,则同返回值为1时的行为相同。
# sentinel notification-script <master-name> <script-path>
sentinel notification-script mymaster /var/redis/notify.sh

# 这个脚本应该是通用的,能被多次调用,不是针对性的。
# sentinel client-reconfig-script <master-name> <script-path>
sentinel client-reconfig-script mymaster /var/redis/reconfig.sh

配置哨兵

环境说明

主机名 IP 操作系统
node1 192.168.100.101 CentOS7
node2 192.168.100.102 CentOS7
node3 192.168.100.103 CentOS7

配置主节点(node1)

1
2


配置从节点(node2、node3)

1
2


集群

Codis

Redis-Cluster

常见问题

应用场景

Redis应用场景 说明
手机验证码 基于过期时间
数据库缓存 基于list实现
队列 基于list实现
存储配置(配置文件信息、统一Session存储)
搜索
对搜索结果进行排序
自动补全
分布式锁 基于watch机制实现乐观锁
最新列表 基于ZSET实现
排行榜 基于ZSET实现
消息通知 基于消息发布订阅+任务队列(List类型的LPUSH和RPOP(左进右出))实现
用户Timeline/Feeds 关注的人、主题、品牌的动态。
反垃圾系统 制定一系列反垃圾规则,其中有些规则可以利用redis做实时分析,譬如:1分钟评论不得超过2次、5分钟评论少于5次等采用sorted set将最近一天用户操作记录起来。
存储社交关系 譬如将用戶的好友/粉丝/关注,可以存在一个sorted set中,score可以是timestamp,这样求两个人的共同好友的操作,可能就只需要用求交集命令即可。
限制访客访问频率 进行各种数据统计的用途是非常广泛的,比如想知道什么时候封锁一个IP地址。INCRBY命令让这些变得很容易,通过原子递增保持计数;GETSET用来重置计数器;过期属性expire用来确认一个关键字什么时候应该删除。

缓存更新策略

场景 说明
读取 先读缓存,缓存没有,再读数据库
更新 先删除缓存,再更新数据库
删除 先删除缓存,再删除数据库
添加 先添加数据库,再添加缓存

缓存穿透

缓存穿透介绍

名词 原因 经过 结果
缓存穿透 先查缓存,缓存不存在,再查询数据库返回查询结果
查询的某一个数据在缓存中一直不存在,就会造成每一次请求都查询DB 缓存就失去了意义,在流量大时,可能DB就挂掉了。

解决缓存穿透问题?

方案 说明
布隆过滤器 使用布隆过滤器提前拦截,不合法就不让这个请求到数据库层。

缓存雪崩

缓存雪崩介绍

名词 原因 经过 结果
缓存雪崩 设置缓存时采用了相同的过期时间 缓存在某一时刻同时失效,请求全部转发到DB DB瞬时压力过重雪崩

解决缓存雪崩问题

方案 说明
设置不同过期时间 简单方案就时讲缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。
定时更新 定时更新,假如缓存过期时间为60分钟,则单独设置一个线程每59分钟去负责更新缓存。

缓存击穿

缓存击穿介绍

名词 原因 经过 结果
缓存击穿 缓存在某个时间点过期的时候,恰好在这个时间点对这个Key有大量的并发请求过来 这些请求从后端DB加载数据并回设到缓存 瞬间把后端DB压垮

解决缓存击穿问题

方案 说明
互斥锁 使用互斥锁,同一时刻只允许一个线程去构建缓存,其他线程等待构建完毕后去缓存取。
定时更新 定时更新,假如缓存过期时间为60分钟,则单独设置一个线程每59分钟去负责更新缓存。

双写一致性问题

双写一致性问题介绍

名词 原因 经过 结果
双写一致问题 1. 缓存服务器挂了
2. 网络问题或网络延迟
3. ...
修改了数据库,没有及时修改缓存 缓存跟数据数据不一致

如何保证数据库与Redis双写一致性?

标题 说明
业务层实现 1. 在修改数据库后,无法修改缓存,这时候可以将这条数据放到数据库或队列中
2. 同时启动一个异步任务定时去检测缓存服务器是否连接成功,一旦连接成功则从数据库中按顺序取出修改数据,依次进行缓存最新值的修改。
基于binlog订阅方式实现 使用binlog订阅组件。
如:canal。

选择持久化方式

快照(snapshotting)、只追加文件(AOF)两种持久化方式既可以同时使用,又可以单独使用,在某些情况下甚至可以两种方法都不使用,具体选择哪种持久化方式需要根据用户的数据以及应用来决定。 AOF的数据丢失保护级别比快照方式要高。

持久化方式 适用场景
快照(snapshotting) 1. 数据量较少
2. 对数据丢失容忍度相对较高
只追加文件(AOF) 1. 数据量较大
2. 对数据丢失容忍度相对较低

慎用发布订阅模式

慎用发布订阅模式的原因 说明
Redis系统稳定性 1. 对于旧版Redis来说,如果一个客户端订阅了某个或某些频道,但它读取消息的速度却不够快的话,那么不断积压的消息就会使得Redis输出缓冲区的体积变得越来越大,这可能导致Redis的速度变慢,甚至直接崩溃。也可能导致Redis被操作系统强制杀死,甚至导致操作系统本身不可用。
2. 新版的Redis不会出现这种问题,因为它会自动断开不符合client-output-buffer-limit pubsub配置选项要求的订阅客户端。
数据传输的可靠性 任何网络系统在执行操作时都可能会遇上断线情况,而断线产生的连接错误通常会使得网络连接两端中的其中一端进行重新连接。
但是,如果客户端在执行订阅操作的过程中断线,那么客户端将丢失在断线期间发送的所有消息。
因此依靠频道来接收消息的用户可能会对Redis提供的PUBLISH命令和SUBSCRIBE命令的语义感到失望。

配置主从复制注意事项

配置主从复制注意事项 说明
内存分配 最好让主服务器只使用50%~65%的内存,留下一部分内存用于执行BGSAVE命令和创建记录写命令的缓冲区。
数据丢失 从服务器在进行初始连接时,数据库中原有的所有数据都将丢失,并被替换成主服务器发来的数据。
不适用场景 Redis不支持主主复制。

Redis与Memcached对比

对比项 Redis Memcached
数据存储类型 1. String
2. List
3. Set
4. Hash
5. ZSet
1.文本型
2. 二进制(新版本支持)
网络IO模型 单进程模式(Reactor模型,反应炉) 多线程、非阻塞IO模式
事件库 自封装简易AeEvent LibEvent事件库
持久化支持 1. RDB
2.AOF
不支持

Redis HA 方案

方案 说明
keepalived 通过 keepalived 的虚拟 IP,提供主从的统一访问,在主出现问题时, 通过 keepalived 运行脚本将从提升为主,待主恢复后先同步后自动变为主,该方案的好处是主从切换后,应用程序不需要知道(因为访问的虚拟 IP 不变),坏处是引入 keepalived 增加部署复杂性,在有些情况下会导致数据丢失
zookeeper 通过 zookeeper 来监控主从实例, 维护最新有效的 IP, 应用通过 zookeeper 取得 IP,对 Redis 进行访问,该方案需要编写大量的监控代码
sentinel 通过 Sentinel 监控主从实例,自动进行故障恢复,该方案有个缺陷:因为主从实例地址( IP & PORT )是不同的,当故障发生进行主从切换后,应用程序无法知道新地址,故在 Jedis2.2.2 中新增了对 Sentinel 的支持,应用通过 redis.clients.jedis.JedisSentinelPool.getResource() 取得的 Jedis 实例会及时更新到新的主实例地址

源码阅读笔记

哈希表

哈希表的查询效率非常高,复杂度为O(1),通常关注性能的地方都会用到这个东西。 缓存系统,就是一个哈希表。只是通常哈希表的场景都是在本机,把哈希表放到远程的机器上,本机通过网络访问哈希表,就变成现在的缓存系统了。

常见错误

error: jemalloc/jemalloc.h: No such file or directory

问题分析

libc 并不是默认的 分配器, 默认的是 jemalloc, 因为 jemalloc 被证明 有更少的 fragmentation problems 比libc。

解决办法

1
$ make MALLOC=libc

LOADING Redis is loading the dataset in memory

错误描述

Redis报错:

1
2
3
$ edis-cli
127.0.0.1:6379> ping
(error) LOADING Redis is loading the dataset in memory

原因分析

redis.conf中maxmemory默认是3G,当redis中dump.rdb文件到达3G时,所有redis的操作都会抛出此异常。

解决办法

  1. redis.conf中maxmemoy设置大一些
    1
    maxmemory <byte>

换算参考 在线文件大小(bit,bytes,KB,MB,GB,TB)转换换算

  1. 删除 dump.rdb文件。

第三方推荐

坚持原创技术分享,您的支持将鼓励我继续创作!
0%