Redis-基础和应用篇

2020,到新公司这一年多以来,更新文章和总结知识的习惯被丢掉了。我复盘了下自己,原因不是公司技术氛围不好,也不是每天业务需求太多,其根本原因还是---惰性。作为我们技术人随着年龄的增长,精力也会被生活中许多琐碎的事情分散,但我们不应该忘记当初写下第一行代码时的初衷。我们一定要明白持之以恒、长远规划、阶段性复盘的重要性。2021新的一年,新的心态,新的目标,GO! GO! GO!!!

本文是读钱文品《Redis深度历险》的读书笔记

一、redis应用

1、记录帖子点赞数、评论数和点击数(hash)

2、记录用户的帖子ID列表,便于快速显示用户的帖子列表(zset)

3、记录帖子的标题、摘要、作者和封面信息,用户列表页展示(hash)

4、记录帖子的点赞用户ID列表,评论ID列表,用于显示和去重计数(hash)

5、缓存近期热帖内容(帖子内容的空间占用比较大),减少数据库压力(hash)

6、记录帖子的相关文章ID,根据内容推荐相关帖子(list)

7、如果帖子ID是整数自增的,可以使用redis来分配帖子ID(计数器)

8、收藏集和帖子之间的关系(zset)

9、记录热榜帖子ID列表、总热榜和分类热榜(zset)

10、缓存用户行为历史,过滤恶意行为(zset、hash)

11、保证同一用户不会中奖两次(set)

二、redis数据结构

string(字符串)、list(列表)、hash(字典)、set(集合)、zset(有序集合)

1. string(字符串)

其内部字符串是一个动态字符串,类似于ArrayList的动态扩容。以此减少频繁分配内存的开销。字符串长度小于1M时,成倍扩容;大于1M时,只增加1M;最大长度512M。

使用场景:

缓存用户登录信息。token作为key,用户信息使用JSON序列化成字符串,获取时再反序列化。

常用命令 set name value #存值 get name #取值 exists name #判断 del name mset name1 name2 value1 value2 #批量取 mget name1 name2 ..... #批量取 expire name m秒 #m秒后过期 setex name m秒 value #存值,并且设置过期时间 setnx name value #存值,如果name已经存在,就返回0 set name 1 #设置为整数 incr name #还可以自增 incrby name 整数 #加 2. list(列表)

类似于LinkedList。插入删除块,查询慢。

使用场景

常用于异步队列实现(先进先出)

常用命令 rpush name value1 value2... #入队 llen name #队列长度 lpop name #出队 value1 3. hash(字典)

类似于HashMap

使用场景

可以对存储结构中每个字段单独存储。过期时间是针对真个hash对象,而不是单独的子key.

常用命令 hset key filed1 value1 hset key filed2 value2 #存 hget key filed1 #取 4. set(集合)

sadd, smembers, scard

5. zset(有序集合)

zadd, zrange,zrank, zrem,zcard

三、HyperLogLog

场景:估数、精确度要求不高场景(统计网站的PV 和UV)

命令 pfadd、pfcount、pfmerge

内存占用比set小,有一定的误差

四、布隆过滤器

原理:布隆过滤器是一个BIT数组

场景:信息推荐去重(微博推荐刷新时过滤已经看过的信息),垃圾邮件过滤、爬虫系统过滤已爬内容、解决缓存穿透问题

布隆过滤器可以判断某个数据一定不存在,但是无法判断一定存在(不精确的SET)

占用内存极少,并且插入和查询速度都足够快。

缺点,无法删除数据;随着数据的增加,误判率会增加

Redisson 实现

五、Reids6种淘汰策略

volatile-lru:从设置了过期时间的数据集中,选择最近最久未使用的数据释放;

allkeys-lru:从数据集中(包括设置过期时间以及未设置过期时间的数据集中),选择最近最久未使用的数据释放;

volatile-random:从设置了过期时间的数据集中,随机选择一个数据进行释放;

allkeys-random:从数据集中(包括了设置过期时间以及未设置过期时间)随机选择一个数据进行入释放;

volatile-ttl:从设置了过期时间的数据集中,选择马上就要过期的数据进行释放操作;

noeviction:不删除任意数据(但redis还会根据引用计数器进行释放),这时如果内存不够时,会直接返回错误。

默认策略是noeviction

推荐使用的策略是volatile-lru

通过maxmemory-samples配置样本数量,默认为5

缓存淘汰算法(LFU、LRU、ARC、FIFO、MRU)

六、Redis 持久化方案:

RDB 默认方式 (RDB持久化即通过创建快照的方式进行持久化,保存某个时间点的全量数据。)

AOF (Append-Only-File持久化即记录所有变更数据库状态的指令,以append的形式追加保存到AOF文件中)

如果Redis只是用来做缓存服务器,比如数据库查询数据后缓存,那可以不用考虑持久化,因为缓存服务失效还能再从数据库获取恢复。

七、缓存和数据库数据一致性(并发竞争问题)

延时双删策略(在写库前、后进行redis.del,并且设定合理的延时时间。)

读取binlog分析 ,利用消息队列(rabbitmq、kafka), 推送更新各台的redis缓存数据

八、缓存穿透

现象:用户大量并发请求的数据(key)对应的数据在redis和数据库中都不存在,导致尽管数据不存在但还是每次都会进行查DB。

解决方案:从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null

九、缓存击穿

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdgzd.html