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. Python中判断一个中文是否中文数字的方法

    Python内置功能非常强大,在字符串内置函数中提供了一个判断字符串是否全数字的方法,而且这个方法不只是简单判断阿拉伯数字,包括中文数字和全角的阿拉伯数字都认识,这个函数就是字符串的isnumeric ...

  2. MySQL必知必会详细总结

    一.检索数据 1.检索单个列:SELECT prod_name FROM products; 2.检索多个列:SELECT prod_id,prod_name,prod_price FROM prod ...

  3. 能否让APP永不崩溃—小光与我的对决

    前言 关于拦截异常,想必大家都知道可以通过Thread.setDefaultUncaughtExceptionHandler来拦截App中发生的异常,然后再进行处理. 于是,我有了一个不成熟的想法.. ...

  4. 学习笔记:Splay

    代码适中.非常灵活的平衡树. 需要前置:二叉搜索树. 一些基础的函数: int idx, ch[N][2], cnt[N], sz[N], fa[N]; /* idx 是节点计数, ch[i][0 / ...

  5. 【复习笔记】重习 AC 自动机

    发现已经忘了许多....于是复习一下 基础要点概况 AC 自动机基于 Trie 树 的结构,即构建 AC 自动机前需要先建 Trie. 一个状态中除了转移 \(\delta\) 之外还有失配指针 \( ...

  6. 深度剖析目标检测算法YOLOV4

    深度剖析目标检测算法YOLOV4 目录 简述 yolo 的发展历程 介绍 yolov3 算法原理 介绍 yolov4 算法原理(相比于 yolov3,有哪些改进点) YOLOV4 源代码日志解读 yo ...

  7. 四、Zookeeper伪集群搭建

    伪集群模式 Zookeeper不但可以在单机上运行单机模式 Zookeeper,而且可以在单机模拟集群模式 Zookeeper的运 行,也就是将不同实例运行在同一台机器,用端口进行区分,伪集群模式为我 ...

  8. 应用案例——高并发 WEB 服务器队列的应用

    在高并发 HTTP 反向代理服务器 Nginx 中,存在着一个跟性能息息相关的模块 - 文件缓存. 经常访问到的文件会被 nginx 从磁盘缓存到内存,这样可以极大的提高 Nginx 的并发能力,不过 ...

  9. 网络 IO 模型简单介绍

    一.同步阻塞 IO(BIO) 当用户线程调用了 read 系统调用,内核(kernel)就开始了 IO 的第一个阶段:准备数据.很多时候,数据在一开始还没有到达(比如,还没有收到一个完整的Socket ...

  10. 想用selenium ,先了解html 基础知识(5)

    二.HTML语法---了解!1.HTML超文本标记语言,是网页设计使用的语言.2.从<html>开始,到</html>结束,里面包括head和body两个部分,我们测试人员关心 ...