redis 和 memecache 有什么区别?
1 memcache所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型
2 redis的速度比memcached快很多
3 redis可以持久化其数据
4 memcache不支持主从
5 memcache不支持分片
为什么redis这么快?
完全基于内存,绝大部分请求是纯粹的内存操作,执行效率高
数据结构简单,对数据操作也简单
采用单线程,单线程也能处理高并发请求,想多核也可启动多实例
使用多路I/O复用模型,非阻塞IO
从海量数据中查询出某一固定前缀的key
查询key:keys pattern + // *,?,[]
KEYS指令一次性返回所有匹配的key
键的数量过大会使服务卡顿
所以,出现了:
SCAN cursor [MATCH pattern] [COUNT count]
➢基于游标的迭代器,需要基于.上一-次的游标延续之前的迭代过程
➢以0作为游标开始一-次新的迭代,直到命令返回游标0完成一-次遍历
➢不保证每次执行都返回某个给定数量的元素,支持模糊查询
➢一-次返回的数量不可控,只能是大概率符合count参数
scan 0 match k1* count 10含义:
从0开始找到10个满足k1开头的字段,会返回cursor和找到的部分数据。
tip:cursor不一定递增,可能获得重复数据,需要去重。
redis 怎么实现分布式锁?
Redis 分布式锁其实就是在系统里面占一个“坑”,其他程序也要占“坑”的时候,占用成功了就可以继续执行,失败了就只能放弃或稍后重试。
占坑一般使用 setnx(set if not exists)指令,只允许被一个程序占有,使用完调用 del 释放锁
配合EXPIRE key seconds
设置key的生存时间,当key过期时(生存时间为0) ,会被自动删除
风险:原子性没有得到满足,所以不建议。
解决办法:
SET key value [EX seconds] [PX milliseconds] [NX|XX]
➢EX second :设置键的过期时间为second秒
➢PX millisecond :设置键的过期时间为millisecond毫秒
.➢NX :只在键不存在时,才对键进行设置操作
➢XX:只在键已经存在时,才对键进行设置操作
➢SET操作成功完成时,返回OK ,否则返回nil
持久化
RDB
快照持久化,保存某个时间点的全量数据。
bgsave:fork一个子进程创建rdb文件,不阻塞服务器进程。
自动触发RDB持久化的方式
1 根据redis.conf配置里的SAVE m n定时触发(用的是BGSAVE )
2 主从复制时,主节点自动触发
3 执行Debug Reload
4 执行Shutdown且没有开启AOF持久化
缺点
RDB方式无论是执行命令还是进行配置,无法做到实时持久化,具有较大可能丢失数据
bgsave每次运行要执行fork操作创建子进程,要牺牲一些性能
存储数量较大时,效率较低
大数据量下的I/O性能较低
基于fork创建子进程,内存产生额外消耗
宕机带来的数据丢失风险
AOF
AOF ( Append-Only-File )持久化:保存写状态
- 记录下除了查询以外的所有变更数据库状态的指令
- 以append的形式追加保存到AOF文件中( 增量)
AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式
恢复策略:
双保险策略,同时开启RDB和AOF,重启后Redis优先使用AOF来恢复数据,降低丢失数据量
优缺点:
RDB优点:全量数据快照,文件小,恢复快
RDB缺点:无法保存最近一次快照之后的数据
AOF优点:可读性高,适合保存增量数据,数据不易丢失
AOF缺点:文件体积大,恢复时间长
RDB-AOF混合持久化方式(默认使用)
BGSAVE做镜像全量持久化, AOF做增量持久化