持久化
两种方式实现持久化,分别是AOF和RDB
RDB即快照持久化,配置文件
save 60 1000
save 900 1
…
形式,表示60s内有1000此 访问就会创建快照,有多个配置的 话只要 满足一条就会触发。
触发时机还有:调用save, bgsave,主从同步sync(bigsave),redis关闭(save)等等
原理:bgsave fork子进程,不阻塞,总 耗时较多,占内存较多,save无法响应save发生时的请求。
丢失:丢失快照 后的数据
AOF:
appendonly no
appendfsync everysec
…
三种级别
always 保证每次都写入文件
everysec表示每秒写入
no让 操作系统决定
原理:每次写入aof文件(缺点,aof文件会比较大可以发送bgrewriteaop缩小文件)
事务
redis不提供悲观锁,提供乐观锁
使用multi开启
期间条件加入缓存队列
exec发送
客户端一般编写模式
while
begin
watch 竞争条件
value = reids 命令 + 竞争条件
if value then
multi
//todo
exec
else
unwatch
end
end
multi ~ exec中间的命令是无法获取上一步的结果的
exec执行的事务中间无法插入其他食物
watch条件被更改事务不会执行(所以需要while不断重试) ,可以用unwatch取消
有序列表的排序
默认是按值来排序,但是当值相同的时候排序会按照名字来排序
锁
watch在高并发的情况下,冲突几率太大,经常重试
setnx:如果没有key,设置一个
def acquire():
while 不超时
if setnx lock identify 失败
continue;
else return; // 还可以加上锁过期时间
end
def release():
while true
watch lock
if get lock == identify //检查锁的持有者是否是自己
del lock
return true
unwatch
return false
end
锁会减少冲突数,但是获取锁会相应减少对应的添加操作性能,要考虑一下。
几个比较重要的命令
BLPOP list 3 // 可以实现消费者队列,3s内向list求数据,没有会阻塞
setnx上文讲过了
zinterstore,zunionstore 很重要,可以用于比较替换,将多个操作变为一个
比如
zunionstore math 2 math min weights 1 1 aggregate min
意思是,目标是math,会把math min 中的最小值 * 1 后存入 math集合。
sort key [BY pattern] [LIMIT start count] [GET pattern] [ASC|DESC] [ALPHA] [STORE dstkey]
案例
redis在文本搜索中的应用。
redis集合特别适合建立反向索引。
何为反向索引
-
I’m happy today.这样一句话,去掉无效词,进行分词处理 happy, today,然后存储为两个happ(set),today(set) ;value就是这篇文章的id。
-
对于用户的搜索也进行分词,根据词性分析,不断对redis集合进行union,diff,inter操作,得到结果非常快。
非数值排序
需要字符串->数字
zset分值部分由float存储 8字节。
如果需要使用非数字排序比如字符串排序一种做法就是对位每个字符转成对应的ascll,但是中文可能不行(中文只能存储更少的字)
提高性能
节约内存
list是双向链表,除了前后指针外,节点还存储了字符串长度和可用空间,使用压缩列表后,结果将不再是双向链表,而是序列,节点不记录可用空间,只记录当前空间和上一个节点的空间
配置由
list-max-ziplist-entries 512 使用压缩列表的最大数
list-max-ziplist-value 64 压缩列表每个节点最大多少
超出后将不适用压缩编码
set如果开启压缩
list-max-ziplist-entries 512 将会以整数数组存储
同时,压缩列表会随着压缩列表的长度增加性能变慢,因此,压缩列表不适宜长度太大,或者说,长度太大就不应该用压缩列表
注意redis key最大长度是512M