Redis5中基本数据类型
- string(字符串):可以包含任何数据,一个key对应一个value;
- hash(哈希):string类型的field和value的映射表,适用于存储对象,格式:key 属性名 属性值 属性名 属性值…name “zhangsan”
- list(列表):是一个链表结构,按照插入顺序排序;底层是一个双向链表,插入数据时可以采用头插(lpush)或者尾插(rpush),格式:lpush key value value…
- set(集合):是string类型的无序集合,格式:sadd key value value …
- zset(有序集合):是string类型元素的有序集合,zset是插入有序的,即自动排序,格式:zadd key 值(int 排序依据) value …
连接远程redis需要的配置
- 绑定的主机地址(默认只允许本机发起访问),因此将下面这行注释;
bind 127.0.0.1 - protected-mode 默认为yes,作用是开启保护默认,没密码+保护模式启动=本地访问,如果没设置密码就需要改为no
- requirepass 你的密码,设置连接redis密码
- redis-cli -h 114.132.48.57 -p 6379 -a 123456 连接远程的redis服务
持久化
RDB实现持久化
RDB
是 Redis 默认的持久化方案。RDB持久化时会将内存中的数据写入到磁盘中,在指定目录下生成一个dump.rdb
文件。Redis 重启会加载dump.rdb
文件恢复数据。
bgsave
是主流的触发 RDB 持久化的方式,执行过程如下:
- 执行
BGSAVE
命令 - Redis 父进程判断当前是否存在正在执行的子进程,如果存在,
BGSAVE
命令直接返回。 - 父进程执行
fork
操作创建子进程,fork操作过程中父进程会阻塞。 - 父进程
fork
完成后,父进程继续接收并处理客户端的请求,而子进程开始将内存中的数据写进硬盘的临时文件; - 当子进程写完所有数据后会用该临时文件替换旧的 RDB 文件。
配置文件
- stop-writes-on-bgsave-error yes :当redis无法写入磁盘的话,直接关闭redis的写操作;
- rdbcompression yes :对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩;
- rdbchecksum yes :在存储快照后,还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭,但是数据的完整性还是推荐开启;
- save :save 时只管保存,其它不管,全部阻塞。手动保存,不建议,并且可以设置多个触发规则;
save 900 1 :在900秒内如果有一个key发生了改变,则会触发一次持久化操作。
优势
- 适合大规模的数据恢复
- 对数据完整性和一致性要求不高更适合使用
- 节省磁盘空间
- 恢复速度快
劣势
- Fork 的时候,内存中的数据被克隆了一份,大致 2 倍的膨胀性需要考虑。
- 虽然 Redis 在 fork 时使用了写时复制技术,但是如果数据庞大时还是比较消耗性能。
- 在备份周期在一定间隔时间做一次备份,所以如果 Redis 意外 down 掉的话,就会丢失最后一次快照后的所有修改。
AOF实现持久化
以日志的形式来记录每个写操作(增量保存),将 Redis 执行过的所有写指令记录下来 (读操作不记录), 只许追加文件但不可以改写文件,redis 启动之初会读取该文件重新构建数据,换言之,redis 重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
AOF 持久化流程
- 客户端的请求写命令会被 append 追加到 AOF 缓冲区内;
- AOF 缓冲区根据 AOF 持久化策略 [always,everysec,no] 将操作 sync 同步到磁盘的 AOF 文件中;
- AOF 文件大小超过重写策略或手动重写时,会对 AOF 文件 rewrite 重写,压缩 AOF 文件容量;
- Redis 服务重启时,会重新 load 加载 AOF 文件中的写操作达到数据恢复的目的。
AOF 默认不开启
可以在 redis.conf 中配置文件名称默认为 appendonly.aof 文件中开启,AOF 文件的保存路径,同 RDB 的路径一致。
AOF 和 RDB 同时开启,redis 听谁的?
AOF 和 RDB 同时开启,系统默认取 AOF 的数据(数据不会存在丢失)。
AOF 启动、修复、恢复
AOF 的备份机制和性能虽然和 RDB 不同,但是备份和恢复的操作同 RDB 一样,都是拷贝备份文件,需要恢复时再拷贝到 Redis 工作目录下,启动系统即加载。
正常恢复
修改默认的 appendonly no,改为 yes。
将有数据的 aof 文件复制一份保存到对应目录 (查看目录:config get dir)。
恢复:重启 redis 然后重新加载。
异常恢复
修改默认的 appendonly no,改为 yes。
如遇到 AOF 文件损坏,通过 /usr/local/bin/ redis-check-aof–fix appendonly.aof 进行恢复。
备份被写坏的 AOF 文件。
恢复:重启 redis,然后重新加载。
AOF 同步频率设置
appendfsync always:始终同步,每次 Redis 的写入都会立刻记入日志;性能较差但数据完整性比较好。
appendfsync everysec:每秒同步,每秒记入日志一次,如果宕机,本秒的数据可能丢失。
appendfsync no:redis 不主动进行同步,把同步时机交给操作系统。
缓存穿透
缓存穿透就是查询一个不存在的数据,因为缓存是不命中时被动写入的,如果DB查不到数据则不写入缓存,这将导致这个不存在的数据,每次请求都要去DB查询,失去了缓存的意义。
解决办法:
- 缓存空值,这样就不会再去查询数据库
- 采用布隆过滤器
缓存雪崩
缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻全部失效,请求全部转发到DB,DB瞬时压力过重挂掉。
解决办法:
- 在设置过期时间时加上一个随机值,使得过期时间分散些
缓存击穿
缓存击穿加上当大量请求查询同一个key时,此时这个key正好同时失效,导致大量请求都落到数据库。
缓存击穿是查询缓存中失效的key,缓存穿透是查询不存在的数据
解决办法:
- 加分布式锁,第一个请求线程可以拿到锁,拿到锁的线程查询到了数据后会写入缓存,其他线程获取锁失败会等待50ms后重新到缓存中获取数据,这样就可以避免大量请求落到数据库。
Redis内存优化
- 使用String类型时,对key值尽量使用简写,value值只保存需要的数据,尽量对数据进行精简;
- 使用对象共享池,在存储0~9999之间的整数时,会直接指向Redis提前创建好的整数对象共享池中,减少内存占用;比如 set 张三 18 与 set 李四 18 他们的value指向的都是同一个对象;
注意:
1、如果Redis使用了maxmemory限制最大占用内存大小且启用了LRU策略,则共享线程池失效;(因为LRU策略需要记录每个键值对的访问时间)
2、集合类型的编码采用 ziplist 编码,并且集合内容是整数,也不能共享一个整数对象。