分布式锁
主要原理:利用setnx命令占坑
核心命令:set lock_codehole true ex 5 nx
http://zhangtielei.com/posts/blog-redlock-reasoning.html
官方的分布式锁实现:redlock算法 https://redis.io/topics/distlock 这里有php的实现
hyperLogLog
功能类似set,但是他只提供计数功能,而且去重有一定误差(百分之零点几),优点是占用空间小(固定的12K)
适合存储数量很大但是对去重精确性要求不高的数据(比如网站UV值)
PFADD,PFCOUNT,PFMERGE三个命令
布隆过滤器
上面的hyperLogLog只提供计数,没有查值的功能。布隆过滤器可以判断值是否存在。
简化的set,有一定误差
是一个插件,可以通过docker安装:docker pull redislabs/rebloom
命令:bf.add,bf.exists,bf.madd,bf.mexists
充分利用上述结构(包括set)的去重特性很重要
例:爬虫中url的去重
限流策略
https://www.jianshu.com/p/d44a63bce187
geohash地理位置距离排序
geohash是一种通用的地理算法,mysql、mongodb等也有对应的支持,有空可以研究一下。
https://www.jianshu.com/p/a48eec659952
scan和keys对比
复杂度虽然也是 O(n),但是它是通过游标分步进行的,不会阻塞线程;
提供 limit 参数,可以控制每次返回结果的最大条数,limit 只是一个 hint,返回的结果可多可少;
同 keys 一样,它也提供模式匹配功能;
服务器不需要为游标保存状态,游标的唯一状态就是 scan 返回给客户端的游标整数;
返回的结果可能会有重复,需要客户端去重复,这点非常重要;
遍历的过程中如果有数据修改,改动后的数据能不能遍历到是不确定的;
单次返回的结果是空的并不意味着遍历结束,而要看返回的游标值是否为零;
scan 0 match test_* count 1000
-
"13976"
-
"test_12"
-
"test_33"
-
"test_534"
-
注意点:
0代表游标位置,从0开始。scan会返回结束游标位置,如果不是0,应该从这个位置继续扫描。0代表扫描完毕,比如上面的返回结果是13976,下一条scan指令应该是:scan 13976 match test_* count 1000;
这个count不是取出元素的个数,而是一次scan的字典槽位数量,可能limit1000获取到的元素个数值有10个;
zscan、hscan、sscan等可以遍历指定集合内的元素。
数据持久化
快照:全量备份,把内存中的数据存储到磁盘上
AOF:增量备份,把执行的指令记录下来
为什么redis不适合做数据库,只适合做缓存?
1.成本-首先成本原因,因为Redis是内存数据库,而内存相对于磁盘来说虽然性能很高,但是成本更高,在做大量数据存储时成本问题尤为突出
2.持久性-Redis数据丢失率,上面看到不管是RDB还是AOF都会进行IO操作,那么在持久化过程为了提高性能就需要降低保存频率,那么必然会有数据丢失的情况,无法保证数据的完整性
3.查询特性-Redis的数据特性导致查询功能特性较少,而数据库一般需要支持多样查询,redis无法适用这样的场景
4.事务特性:redis不具备事务特性,尤其是在分布式环境下尤为特出
管道
本质是在客户端把多个命令一次性发送、一次性接收,减少网络开销。
laravel实现:
Redis::pipeline(function ($pipe) {
for ($i = 0; $i < 1000; $i++) {
$pipe->set("key:$i", $i);
}
}); // 管道操作,在一次操作插入或者读出多次
$redis = Redis::keys("*");
var_dump($redis);exit;
事务
multi/exec/discard对应begin/commit/rollback
注意:
redis事务没有原子性,比如执行了3条指令,其中一条失败了,并不会回滚所有指令,另外两条仍然会被执行。
所以redis的事务只满足了隔离性
watch命令
分布式锁相当于悲观锁,watch相当于乐观锁
> watch books
OK
> incr books # 被修改了
(integer) 1
> multi
OK
> incr books
QUEUED
> exec # 事务执行失败
(nil)
注意:
-
exec返回nil时表示books被修改了所以事务执行失败
-
watch要在mutil之前执行
-
可以用unwatch取消监事,如果执行了exec或discard会自动取消所有对key的监视
分布式的一些东西,暂时不深入研究了,知道一些概念用到的时候再学
主从同步
Redis Sentinel(哨兵)主服务挂了以后自动切换到从服务
Redis cluster 官方的redis集群
5.0以后的新数据结构:
Stream.用来替代pub/sub。准备另起一篇来记录stream的东西。
网友评论