读Redis感悟

Redis深度历险 ,核心原理与应用实践

授人以鱼不如授人以渔

Redis 可以做什么?

  1. 记录帖子的点赞数、评论数和点击数( hash )。
  2. 记录用户的帖子 ID 列表(排序〉,便于快速显示用户的帖子列表( zset )。
  3. 记录帖子的标题、摘要、作者和封面信息, 用于列表页展示( hash )。
  4. 记录帖子的点赞用户 ID 列表,评论 ID 列表,用于显示和去重计数( zset )。
  5. 缓存近期热帖内容(帖子内窑的空间占用比较大),减少数据库压力( hash )。
  6. 记录帖子的相关文章 ID ,根据内容推荐相关帖子 (list) 。
  7. 如果帖子 ID 是整数自增的,可以使用 Redis 来分配帖子 ID (计数器)。
  8. 收藏集和帖子之间的关系(zset)。
  9. 记录热榜帖子 ID 列表、总热榜和分类热榜( zset )。
  10. 缓存用户行为历史,过滤恶意行为( zset, hash )。

上述情况 ,适用在数据请求压力很大的时候。

万丈高楼平地起——Redis基础数据结构

5种基础数据结构

String(字符串) ,list (列表),hash(字典),set( 集合),zset (有序列表).


String:

string内部就是一个字符数组,相当于java里面的ArrayList。Redis所有的数据结构都以唯一的key字符串作为名称,然后通过这个唯一的key值来获取相应的value值。不同类型的数据结构差异在于value结构不一样。

缓存用户信息的过程:将用户信息结构体使用JSON序列化成字符串,之后将序列号的字符串塞进Redis缓存,取用户信息会经过一次反序列化过程。

常用命令:

set key value exists key del key get key

mget key1 key2 key3 mset key1 value key2 value key3 value

过期和 set 命令扩展

expire key 5 #5s 后过期 setex key 5 value # 5s 后过期,等价 set+expire

setnx key value #如果 key不存在就执行set 创建

计数

如果 value 值是一个整数,还可以对它进行自增操作。自增的范围在 signed long 最大值和最小值之间,超出了这个范围, Redis会报错。

incrby key number

9223372036854775807 #Long.Max

list

Redis 的列表相当于 Java 语言里面的 LinkedList。Redis 的列表结构常用来做异步队列使用。将需要延后处理的任务结构体序列化成字符串,塞进 Redis 的列表,另 一个线程从这个列表中轮询数据进行处理。

右边进左边出:队列 先进先出

右边进右边出:栈 先进后出 与队列相反,使用场景不多。

慢操作

lindex 相当于 Java 链表的 get(int index 方法,对链表进行遍历,性能随index增大而变差,ltrim 来实现一个定长的链表,两个参数 start_ index 和end_ index 定义了 一个区间,在这个区间内的值 ltrim 保留

rpush key value1 value2 value3 lrange key 0 -1 #获取所有元素, O(n )慎用

ltrim books 1 0 OK #这其实是清空了整个列表 因为区间范围长度为负

快速列表

Redis 底层存储是"快速链表"(quicklist)的一个结构。

首先在列表元素较少的情况下,会使用一块连续的内存储存,是压缩列表(ziplist),Redis 将链表和 ziplist 结合起来组成了 quicklist ,也就是将多个 ziplist 使用双向指针串起来使用。quicklist满足了快速的插入删除性能,不会出现太大的空间冗余。

hash

Redis 的字典相当于 Java 语言里面的 HashMap(数组+链表) ,是无序字典,Redis 的字典的值只能是字符串,另外它们 rehash 的方式不一样,Redis采用了渐进式rehash策略,渐进式 rehash会在rehash的同时保留新旧两个hash结构 ,在后续的定时任务以及 hash操作指令中循序渐进地将旧hash的内容 一点点地迁移到新 hash 结构中。当搬迁完成了,就会使用新的hash结构取代。hash结构的存储消耗要高于单个字符串。

常用命令: hset key field value #命令行的字符串如果包含空格,要用引号括起来,如果做更新操作,所以返回0

hgetall key hlen key hget key field

hmset key field1 value1 field2 value2 field3 value3 #批量 set

hincrby key field value increment #增加

set

相当于 Java 语言里面的 HashSet,是无序的、唯一的。内部实现相当于一个特殊的字典,字典中所有的 value 都是一个值 NULL,当集合中最后一个元素被删除时,数据结构自动被删除,内存回收。可以用于来存储在某活动中中奖的用户 ID。

常用命令: sadd key value smembers key sismember key value #查询某个 value 是否存在,相当于 contains(o) scard key #获取长度相当于 count () spop key #弹出一个

zset

它类似于Java的SortedSet和HashMap 的结合体, 保证了内部 value 的唯一性,另一方面它可以给每个 value 赋予一个 score ,代表这个 value 的排序权重。它的内部实现用的是一种叫作“跳跃列表”的数据结构。可以用来存储粉丝列表, value值是粉丝的用户ID, score是关注时间。还可以用来存储学生的成绩,value值是学生的 ID, score 是他的考试成绩。

zadd key score member zrange key 0 -1 #按 score 排序列出,参数区间为排名范围

zrevrange key 0 -1 #按 score 逆序列出,参数区间为排名范围

zcard key #相当于 count () zscore key value#获取指定 value的score

zrank key value #排名 zrangebyscore key min max #根据分值区间遍历 zset

zrem key value #删除 value

跳跃列表

zset 内部的排序功能是通过"跳跃列表”数据结构来实现的,定位插入点时,先在顶层进行定位,然后下潜到下一级定位,一直下潜到最底层找到合适的位置,将新元素插进去。

原文地址:https://www.cnblogs.com/zzy8080/p/14008535.html