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

九、缓存击穿

  • 现象:缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。
  • 解决方案:

1.设置热点数据永远不过期

2.接口限流与熔断,降级

3.加互斥锁

4.布隆过滤器

十、缓存雪崩

  • 现象:大量key同一时间点失效,同时又有大量请求打进来,导致流量直接打在DB上,造成DB不可用。
  • 解决方案:

1.设置key永不失效(热点数据);

2.设置key缓存失效时候尽可能错开;

3.使用多级缓存机制,比如同时使用redsi和memcache缓存,请求->redis->memcache->db;

4.购买第三方可靠性高的Redis云服务器;

十一、Redis热点key处理

1 热点key发现

  • 监控热key(抓包程序抓redis监听端口的数据,抓到数据后往kafka里丢。接下来,flink流式计算系统消费kafka里的数据,进行数据统计即可)
  • 通知系统做处理

2 解决方案

  • 本地缓存(利用ehcache或HashMap将发现的热key加载到jvm,热key直接走jvm查询)

  • 集群(把这个热key,在多个redis上都存一份)

  • 阿里云Redis已经在内核层面解决热点key问题

3. 热key的危害

  • 流量集中,达到物理网卡上限。

  • 请求过多,缓存分片服务被打垮。

  • DB 击穿,引起业务雪崩。

十二、拒绝大KEY

  • 集群环境,大key会导致数据迁移卡顿
  • 如果被删除时,内存一次性回收,也会卡顿
  • 扩容时,会一次性申请更大的内存,也会卡顿
  • 注意:如果Redis内存起伏较大,很有可能是大key导致,这时需要定位大key并优化
  • 定位大key可以使用scan、或者redis-cli指令完成

十三、Redis是单线程的,但Redis为什么这么快

  • 1、基于内存
  • 2、数据结构和操作简单
  • 3、多路I/O复用模型(非阻塞IO)
  • 4、单线程避免了不必要的上下文切换和竞争条件

十四、漏斗限流

分布式限流:redis-cell

单机:Google的guava包提供了RateLimiter类

限流的常见算法有以下三种:

1.时间窗口算法

2.漏桶算法

3.令牌算法

十五、GEO

  • Redis通过GeoHash算法实现附近的人查询功能;
  • 内部数据结构是zset,通过score还原就可以得到原始坐标;
  • 集群环境中单个key对应的数据不宜超过1M,如果超过需要按相应业务规则拆分降低key的数据大小。

十六、scan

  • 通过游标分步进行,相比于keys,不会阻塞线程
  • 提供limit参数可以控制返回结果条数

Redis-基础和应用篇的更多相关文章

  1. 【进阶之路】Redis基础知识两篇就满足(二)

    导言 大家好,我是南橘,一名练习时常两年半的java练习生,这是我在博客园的第二篇文章,当然,都是要从别处搬运过来的,不过以后新的文章也会在博客园同步发布,希望大家能多多支持^_^ 这篇文章的出现,首 ...

  2. 【进阶之路】Redis基础知识两篇就满足(一)

    导言 大家好,我是南橘,一名练习时常两年半的java练习生,这是我在博客园的第一篇文章,当然,都是要从别处搬运过来的,不过以后新的文章也会在博客园同步发布,希望大家能多多支持^_^ 这篇文章的出现,首 ...

  3. 二、Redis基本操作——String(实战篇)

    小喵万万没想到,上一篇博客,居然已经被阅读600次了!!!让小喵感觉压力颇大.万一有写错的地方,岂不是会误导很多筒子们.所以,恳请大家,如果看到小喵的博客有什么不对的地方,请尽快指正!谢谢! 小喵的唠 ...

  4. mysql主从复制、redis基础、持久化和主从复制

    一.mysql(mariadb)基础 1.基础命令(centos7操作系统下) 1.启动mysql systemctl start mariadb 2.linux客户端连接自己 mysql -uroo ...

  5. Redis基础知识补充及持久化、备份介绍(二)--技术流ken

    Redis知识补充 在上一篇博客<Redis基础认识及常用命令使用(一)--技术流ken>中已经介绍了redis的一些基础知识,以及常用命令的使用,本篇博客将补充一些基础知识以及redis ...

  6. Redis详解入门篇

    Redis详解入门篇 [本教程目录] 1.redis是什么2.redis的作者3.谁在使用redis4.学会安装redis5.学会启动redis6.使用redis客户端7.redis数据结构 – 简介 ...

  7. Redis基础知识点面试手册

    Redis基础知识点面试手册 基础 概述 数据类型 STRING LIST SET HASH ZSET(SORTEDSET) 数据结构 字典 跳跃表 使用场景 会话缓存 缓存 计数器 查找表 消息队列 ...

  8. Redis基础知识详解(非原创)

    文章大纲 一.Redis介绍二.Redis安装并设置开机自动启动三.Redis文件结构四.Redis启动方式五.Redis持久化六.Redis配置文件详解七.Redis图形化工具八.Java之Jedi ...

  9. Redis详解入门篇(转载)

    Redis详解入门篇(转载) [本教程目录] 1.redis是什么2.redis的作者3.谁在使用redis4.学会安装redis5.学会启动redis6.使用redis客户端7.redis数据结构 ...

  10. 【redis】redis基础命令学习集合

    写在前面 Redis是一个高速的内存数据库,它的应用十分广泛,可以说是服务端必学必精的东西.然而,学以致用,无用则无为.学了的东西必须反复的去用,去实践,方能有真知.这篇文章记录了我在redis学习过 ...

随机推荐

  1. PyQt(Python+Qt)学习随笔:QTreeWidgetItem项的子项索引、删除子项的方法

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 树型部件QTreeWidget中的QTreeWidgetItem项: 获取子项索引 可通过index ...

  2. PyQt(Python+Qt)学习随笔:QAbstractItemView的dragEnabled属性的困惑

    老猿Python博文目录 老猿Python博客地址 dragEnabled属性用于控制视图是否支持拖拽,可以通过dragEnabled().setDragEnabled(bool enable)进行属 ...

  3. python序列化与反序列化(json、pickle)-(五)

    1.什么是序列化&反序列化? 序列化:将字典.列表.类的实例对象等内容转换成一个字符串的过程. 反序列化:将一个字符串转换成字典.列表.类的实例对象等内容的过程 PS:Python中常见的数据 ...

  4. KVM初体验之virt-manager unable to connect to libvirt的处理办法

    解决方法 需要用root身份运行virt-manager

  5. IDEA注册码(附修改hosts文件的方法)

    推荐获取IDEA注册码的网站:http://idea.lanyus.com/ 亲测好用! 也可复制下边的注册码: K71U8DBPNE-eyJsaWNlbnNlSWQiOiJLNzFVOERCUE5F ...

  6. base64 基本使用 和os模块使用

    1  base64 的基本使用 import base64 with open('../static/upload/63bc620d1594779d6a98c53a3a8db1e5.png','rb' ...

  7. Difference between @Bean and @Autowired

    Demo01 1 @SpringBootApplication 2 public class Application { 3 4 @Autowired 5 BookingService booking ...

  8. 云原生网络代理(MOSN)的进化之路

    本文系云原生应用最佳实践杭州站活动演讲稿整理.杭州站活动邀请了 Apache APISIX 项目 VP 温铭.又拍云平台开发部高级工程师莫红波.蚂蚁金服技术专家王发康.有赞中间件开发工程师张超,分享云 ...

  9. 利用302绕过http协议限制

    360某处ssrf漏洞可探测内网信息(附内网6379探测脚本) http://xss.one/bug_detail.php?wybug_id=wooyun-2016-0229611

  10. 精尽Spring MVC源码分析 - HandlerAdapter 组件(四)之 HandlerMethodReturnValueHandler

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...