排序
使用SORT命令,操作集合类,和列表和有序集合类; SORT key Alpha 按照字典顺序排列非数字。SORT key DESC
BY 参数, 可以排序散列类型,甚至是字符串类型(根据名称+通配符) get 排序之后 获取值 store 保存 优化: sort是redis最强大最复杂的命令之一。使用不好很容易成为性能的瓶颈。sort命令时间复杂度O(n+mlogM),n :排序的列表的元素个数,m 返回的元素个数。 n较大是,sort性能较低。 1尽量减少待排序键中的元素的数量(使n小) 2 使用limit参数之后取需要的数据(使m小) 3如果排序数据量较大,尽可能使用store参数将结果缓存。过期时间
expire key seconds 返回1表示成功,0表示失败。(没有键无法设置过期)。pexpire key milli
ttl key, 返回键的剩余寿命,不存在返回-2。永久(默认)返回-1。pttl key presist ,取消过期时间,使其永久。使用set,getset也会消除过期。其他指令均不会消除。watch不会认为到期删除的键是被改变。 expireat , pexpireat ; 使用Unix时间作为参数。 应用:实现访问频率的限制。(1 使用String 的 incre ;2 列表类型:记录时间,次数到了,计算差值)实现缓存
为了提高网站负载能力,通常需要将一些访问频率高,但是对CPU或IO资源消耗较大的操作的结果缓存起来,并且定期过期数据再次更新。例如微博的热搜版,五分钟过期键,重新再计算一次。
然而有些场景,如果大了使用缓存,且过期时间长,则内存占用过多;如果过期时间短,可能导致缓存命中率过低并且浪费大了内存白白闲置。这时:
(内存优先,需要淘汰规则):修改 maxmemory, 限制Redis最大可用内存(单位是字节),超过这个限制会依据 maxmemory-policy 参数指定的策略来删除不需要的键。
LRU:Least Recently Used
事务
事务是一组命令的集合,同命令一样,也是Redis最小的执行单位。
multi 开启事务,接下来的命令会被放到queue中,exec提交,开始执行queue中的命令。 事务可以让事务内的命令依次执行,所以客户端A想要执行几条命令,B客户端发送一条命令,A开启了事务,那么B就不会插入到A客户端的几条命令中执行。错误处理
语法错误,如果有一条命令有语法错误,EXEC时都不执行。
运行错误,没有rollback,只能自己收拾烂摊子。 watch:在事务中观察某个键的变化(因为事务是一次性执行所有指令,最后返回结果。这时候无法根据某一条指令的结果进行下一步的操作) watch可以监控一个或者多个键,一旦其中有一个键被修改(或删除)之后的事务不会执行,执行exec之后,会取消对所有的键的监控。如果不想执行监控了我们可以使用unwatch来取消监控。PS , multi 后的命令是在exec之后执行的。通过CAS操作实现乐观锁消息通知
当页面需要发送邮件,复杂的运算,会阻塞页面的渲染。避免等太久,可以考虑使用其他的进程来达到异步的效果。此处可以详见 P87
特点:松耦合,易于扩展。Redis实现任务队列:
使用Rpop 就可以一直拿,当然避免没有数据还一直执行,使用 BRpop 可以设定超时时间。超过时间,则会返回nil ; 0表示不限制等待,没有就永远阻塞下去。
优先级队列:Bpop key [key...] 0检测多个键,如果所有键没有元素则阻塞。可以优先消费 key在前的消息。发布订阅模式:
publish channel message 向某频道发送消息,只有先订阅,后发布的消息才能获取。
subcribe channel 订阅,订阅状态下的 只能执行 subcribe 、ubsubbirbe 、pSubcribe 、punSubcribe 命令。 收到的消息有三种:subcribe 、 message、unSubcribe按规则订阅:
可以使用pSubcribe,规则支持glob风格。可以重复订阅。退订:pUnSubcribe(只退订psubcribe同理对unsubcribe)
pSubcribe channel?*管道
客户端和redis使用TCP协议链接,此间总耗时,成为往返延时。
(单线程的原因?)在执行多命令时,需要等待上一条命令执行完(即收到redis返回的结果)才能执行。 redis的底层通信协议对管道提供了支持,通过管道可以一次性发送多跳命令并在执行完后一次性将结果返回。通过管道减少与Redis的通信次数。第五章讲到 编程语言在开发时使用管道技术。节省内存:
精简键名和键值
内部编码优化,
redis为每种数据类型都提供了两种内部编码的方式。散列类型是通过散列表实现的。(p94)
查看内部编码的方式 object encoding 字符串:使用 REDIS_ENCODING_EMBSTR 编码储存 字符串(该编码与 REDIS_ENCODING_RAW类似)也是基于sdshdr实现的,不过结构体是在一块连续的内存空间中。 散列类型: 使用 HT 和 ZIPLIST 保存,如果字段个数没有超过 hash-max-ziplist-entries ,和字段长度没有超过 hash-max-ziplist-value 就用ZIPLIST保存。 HT 是 hash table 保存的,可以实现O(1)时间复杂度的赋值和取值。其字段和字段值都是用redisObject,所有优化可以用字符串优化。ZIPLIST 是紧凑型编码,牺牲了部分读取性,换去极高的空间利用率,适合在元素较少时使用。列表: LINKEDLIST ZIPLIST
集合类型:HT INTSET 有序集合类型 SKIPLIST ZIPLIST