Redis可以做什么
- 记录帖子的点赞数、评论数和点击数(hash)
- 记录用户的帖子ID列表(排序),便于快速显示用于的帖子列表(zset)
- 记录帖子的标题、摘要、作者和封面信息,用于列表也展示(hash)
- 记录帖子的点赞用户ID列表,评论ID列表,用户显示和去重计数(zset)
- 缓存近期热帖内容(帖子内容的空间占用比较大),减少数据库压力(hash)
- 记录帖子相关的文章ID,根据内容推荐相关帖子(list)
- 如果帖子的ID是正数自增的,可以使用Redis来分配帖子ID(计数器)
- 收藏集和帖子之间的关系(zset)
- 记录热榜帖子ID列表、总热榜和分类热榜(zset)
- 缓存用户历史行为,过滤恶意行为(zset、hash)
5种基础的数据结构
- string
- list 相当于Java语言里的LinkedList
- hash
- set 集合
- zset 有序列表
分布式锁
- 一般使用setnx 命令,只允许一个客户端占据锁,客户端使用完后,可以使用del指令释放锁。
- 发生异常的时候,占据锁的客户端由于异常而导致del指令没有执行,就会陷入死锁,锁永远得不到释放。这时候可以添加一个过期时间expire,规定时间内如果还有释放锁,就会在到期时自动释放。
- 超时问题 如果在加锁和释放锁之间,程序还没有执行完,锁就被释放了。被其他客户端占有,会导致临界区代码不能严格串行执行。为了解决这个问题。可以在锁的key后面添加一个随机字符串。
延时队列
- 可以使用Redis的list数据结构来作为一部消息队列的使用,使用rpush和lpush操作入列,用lpop和rpop操作出列。
- 如果对了空了怎么办? 如果队列空了,客户端就会不断的实行pop进入死循环,这时候可以使用sleep,让线程睡一会儿。
- 阻塞读 用上面的方法可以解决空队列的问题。但是又有一个小问题,就是睡眠会导致消息的延时,可能在睡眠的时候,消息队列中就有了新的消息。这时候,依然要等待睡眠结束,才能处理消息。这样就导致延时。 可以使用blpop和brpop指令,也就是阻塞读,阻塞读在队列没有数据的时候,会立即进入休眠状态,一旦数据到来,则立刻醒过来。消息的延迟几乎为0.
- 空闲时自动断开 阻塞读的问题在于,如果长时间没有消息,就一直保持连接,占用系统资源,服务器一般会主动断开连接,减少系统资源的占用。
- 延时队列的实现 可以通过redis的zset(有序列表)来实现。将消息序列化成一个字符串作为zset的value,这个消息的到期处理时间作为score,然后用多个线程轮训zset获取到期的任务进行处理。
位图
在开发过程中,有一些bool型的数据需要存取,比如用户一年的签到情况,签到了是1,没签到是0.如果使用普通的k-v,每个用户需要记录365个。当用户上亿的时候,需要的存储空间是惊人的。 为了解决这个问题,redis提供了位图数据结构,这样每天的签到记录只需要占据1位,365天就是365个位,46个字节,大大节省了存储空间
- 统计和查找 使用bitcount来统计指数位置范围内内1的个数,bitpos来查找范围内出现的第一个0 或者第一个1
- 魔术指令bitfield setbit和getbit指定位的值都是单个的,如果要一次操作多个位,就必须要使用管道来处理。 不过在redis 3.2版本以后就新增了bitfield指令,一次性可以进行多个位操作,它有3个子指令,get、set、incrby。
HyperLogLog
如果要统计某个网页每天的uv统计数据,可以通过HyperLogLog来实现,它提供了不精确的去重计数方案,误差范围是0.81%,但是已经可以满足UV统计需求了。 有pfadd和pfcounnt、pfmerge指令。
布隆过滤器
HyperLogLog可以用来统计和估数,但是并不能知道一个数据是否已经在HyperLogLog里面了。 这时候可以使用布隆过滤器 它有bf.add 和 bf.exists两个指令。
简单限流
限流需要存在一个滑动时间窗口,可以通过zset数据结构来实现。
GeoHash
Redis 3.2之后添加了地理位置Geo模块,意味着Redis可以实现搜索附近地理位置的功能。
scan
在redis的维护工作中,需要从成千上万个key中找出特定前缀的key列表来手动处理数据。可以通过scan操作。
线程IO模型
Redis是单线程的,但是不影响效率,因为在内存中,所以效率特别高。 它采用select系列的事件轮训API,采用了非阻塞的IO。
持久化
有两种持久化机制
- 快照 一次全量的备份。 采用COW机制来实现,产生一个子进程来完成快照持久化。
- AOF日志 是连续的增量备份,重启时需要加载所有的指令重放,效率比较低。
事务
从multi开始,可以输入存储若干命令,exec触发执行。