硬核redis总结,看这篇就够了!(代码片段)

Java中文社群 Java中文社群     2022-11-28     667

关键词:

高清思维导图已同步Git:https://github.com/SoWhat1412/xmindfile

总感觉哪里不对,但是又说不上来

会发现底层就是个 双端链表,该链表最大长度为2^32-1。常用就这几个组合。

lpush + lpop = stack 先进后出的栈 

lpush + rpop = queue 先进先出的队列 

lpush + ltrim = capped collection 有限集合

lpush + brpop = message queue 消息队列

一般可以用来做简单的消息队列,并且当数据量小的时候可能用到独有的压缩列表来提升性能。当然专业点还是要 RabbitMQ、ActiveMQ等

则记录扩容位置。

3、dictht数组,两个Hash表。

4、iterators 记录了当前字典正在进行中的迭代器

组合后结构就是如下

dictht[1].use 是动态变化的。

整个过程的重点在于rehashidx,其为第一个数组正在移动的下标位置,如果当前内存不够,或者操作系统繁忙,扩容的过程可以随时停止。

停止之后如果对该对象进行操作,那是什么样子的呢?

1、如果是新增,则直接新增后第二个数组,因为如果新增到第一个数组,以后还是要移过来,没必要浪费时间

2、如果是删除,更新,查询,则先查找第一个数组,如果没找到,则再查询第二个数组。


就可以了解本质了。

后就会发现 Zset用的就是可以跟二叉树媲美的跳跃表来实现有序。跳表就是多层链表的结合体,跳表分为许多层(level),每一层都可以看作是数据的索引这些索引的意义就是加快跳表查找数据速度

每一层的数据都是有序的,上一层数据是下一层数据的子集,并且第一层(level 1)包含了全部的数据;层次越高,跳跃性越大,包含的数据越少。并且随便插入一个数据该数据是否会是跳表索引完全随机的跟玩骰子一样。

跳表包含一个表头,它查找数据时,是从上往下,从左往右进行查找。现在找出值为37的节点为例,来对比说明跳表和普遍的链表。

  1. 没有跳表查询 比如我查询数据37,如果没有上面的索引时候路线如下图:
  2. 有跳表查询 有跳表查询37的时候路线如下图:应用场景:

积分排行榜、时间排序新闻、延时队列。

个桶,也就是 16384 个桶。每个(registers)桶中是一个 6 bit 的数组,这里有个骚操作就是一般人可能直接用一个字节当桶浪费2个bit空间,但是Redis底层只用6个然后通过前后拼接实现对内存用到了极致,最终就是 16384*6/8/1024 = 12KB。

: Redis 它的通讯协议是基于TCP的应用层协议 RESP(REdis Serialization Protocol)。

直接调用 rdbSave ,阻塞 Redis 主进程,导致无法提供服务。2、BGSAVE 则 fork 出一个子进程,子进程负责调用 rdbSave ,在保存完成后向主进程发送信号告知完成。在BGSAVE 执行期间仍可以继续处理客户端的请求

3、Copy On Write 机制,备份的是开始那个时刻内存中的数据,只复制被修改内存页数据,不是全部内存数据。

4、Copy On Write 时如果父子进程大量写操作会导致分页错误。


编码,否则转化为 linkedlist 编码。

3、Hash:hash 对象保存的键值对内的键和值字符串长度小于一定值及键值对。

4、Set:保存元素为整数及元素个数小于一定范围使用 intset 编码,任意条件不满足,则使用 hashtable 编码。

5、Zset:保存的元素个数小于定值且成员长度小于定值使用 ziplist 编码,任意条件不满足,则使用 skiplist 编码。

Redis运行执行耗时,Redis的瓶颈主要在于网络的 IO 消耗, 优化主要有两个方向:

1、提高网络 IO 性能,典型的实现比如使用 DPDK 来替代内核网络栈的方式 

2、使用多线程充分利用多核,典型的实现比如 Memcached。

协议栈优化的这种方式跟 Redis 关系不大,支持多线程是一种最有效最便捷的操作方式。所以Redis支持多线程主要就是两个原因:

1、可以充分利用服务器 CPU 资源,目前主线程只能利用一个核

2、多线程任务可以分摊 Redis 同步 IO 读写负荷

关于多线程须知:

  1. Redis 6.0 版本 默认多线程是关闭的 io-threads-do-reads no
  2. Redis 6.0 版本 开启多线程后 线程数也要 谨慎设置。
  3. 多线程可以使得性能翻倍,但是多线程只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程顺序执行

特性也OK。

提出了  Cache Aside Pattern

失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。

命中:应用程序从cache中取数据,取到后返回。

更新:先把数据存到数据库中,成功后,再让缓存失效

Spark集群中都会出现这样的情况,只是解决方法不同而已(用ZK配合强制杀死)。

集群脑裂问题中,如果客户端还在基于原来的master节点继续写入数据那么新的master节点将无法同步这些数据,当网络问题解决后sentinel集群将原先的master节点降为slave节点,此时再从新的master中同步数据将造成大量的数据丢失。

Redis处理方案是redis的配置文件中存在两个参数

是在Redis基础上的一个服务,采用了基于NIO的Netty框架,不仅能作为Redis底层驱动客户端,还能将原生的RedisHash,List,Set,String,Geo,HyperLogLog等数据结构封装为Java里大家最熟悉的映射(Map),列表(List),集(Set),通用对象桶(Object Bucket),地理空间对象桶(Geospatial Bucket),基数估计算法(HyperLogLog)等结构。

这里我们只是用到了关于分布式锁的几个指令,他的大致底层原理:

Redisson加锁解锁 大致流程图如下:

+ 定期删除。memcached采用的过期策略:惰性删除

全量同步 两种机制。

RateLimiter实现。

9、常见知识点

  1. 字符串模糊查询时用Keys可能导致线程阻塞,尽量用scan指令进行无阻塞的取出数据然后去重下即可。
  2. 多个操作的情况下记得用pipeLine把所有的命令一次发过去,避免频繁的发送、接收带来的网络开销,提升性能。
  3. bigkeys可以扫描redis中的大key,底层是使用scan命令去遍历所有的键,对每个键根据其类型执行STRLEN、LLEN、SCARD、HLEN、ZCARD这些命令获取其长度或者元素个数。缺陷是线上试用并且个数多不一定空间大,
  4. 线上应用记得开启Redis慢查询日志哦,基本思路跟MySQL类似。
  5. Redis中因为内存分配策略跟增删数据是会导致内存碎片,你可以重启服务也可以执行activedefrag yes进行内存重新整理来解决此问题。

1、Ratio >1 表明有内存碎片,越大表明越多严重。

2、Ratio < 1 表明正在使用虚拟内存,虚拟内存其实就是硬盘,性能比内存低得多,这是应该增强机器的内存以提高性能。

3、一般来说,mem_fragmentation_ratio的数值在1 ~ 1.5之间是比较健康的



往期推荐

线程池的7种创建方式,强烈推荐你用它...


Redis的自白:我为什么在单线程的这条路上越走越远?


Redis 6.0 正式版终于发布了!除了多线程还有什么新功能?


关注我,每天陪你进步一点点!


java输入输出案例,看这篇就够了!!!(代码片段)

A+B(1)importjava.util.Scanner;publicclassMainpublicstaticvoidmain(String[]args)Scannersc=newScanner(System.in);while(sc.hasNext())inta=sc.nextInt();intb=sc.nextInt();System.out.prin 查看详情

java输入输出案例,看这篇就够了!!!(代码片段)

A+B(1)importjava.util.Scanner;publicclassMainpublicstaticvoidmain(String[]args)Scannersc=newScanner(System.in);while(sc.hasNext())inta=sc.nextInt();intb=sc.nextInt();System.out.println 查看详情

jdk8线程池看这篇就够了(代码片段)

这可能是最简短的线程池分析文章了。顶层设计,定义执行接口InterfaceExecutor()voidexecute(Runnablecommand);ExecutorService,定义控制接口interfaceExecutorServiceextendsExecutor抽象实现ExecutorService中的大部分方法abstractclassAbstractExecutorServ 查看详情

promise看这篇就够了(代码片段)

一、背景  大家都知道nodejs很快,为什么会这么快呢,原因就是node采用异步回调的方式来处理需要等待的事件,使得代码会继续往下执行不用在某个地方等待着。但是也有一个不好的地方,当我们有很多回调的时候,比如这... 查看详情

zookeeper入门看这篇就够了!!(代码片段)

Zookeeper是什么官方文档上这么解释zookeeper,它是一个分布式服务框架,是ApacheHadoop的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项... 查看详情

zookeeper入门看这篇就够了(代码片段)

简介Zookeeper是一个分布式应用程序的分布式开源协调服务。是ApacheHadoop的一个子项目,主要用来解决分布式应用中经常遇到的一些数据管理问题,例如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的... 查看详情

zookeeper入门看这篇就够了(代码片段)

简介Zookeeper是一个分布式应用程序的分布式开源协调服务。是ApacheHadoop的一个子项目,主要用来解决分布式应用中经常遇到的一些数据管理问题,例如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的... 查看详情

面试率90%的js事件循环eventloop,看这篇就够了!!!(代码片段)

面试率90%的JS事件循环EventLoop,看这篇就够了!!!事件循环(EventLoop)大家应该并不陌生,它是前端极其重要的基础知识。在平时的讨论或者面试中也是一个非常高频的话题。理解JavaScript的事件循环往往伴随着... 查看详情

zookeeper入门看这篇就够了(代码片段)

Zookeeper是什么官方文档上这么解释zookeeper,它是一个分布式服务框架,是ApacheHadoop下的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管... 查看详情

分布式锁看这篇就够了(代码片段)

什么是锁?在单进程的系统中,当存在多个线程可以同时改变某个变量(可变共享变量)时,就需要对变量或代码块做同步,使其在修改这种变量时能够线性执行消除并发修改变量。而同步的本质是通过锁来实现的。为了实现多... 查看详情

android原生tablayout使用全解析,看这篇就够了(代码片段)

...把各种效果的实现一次性讲齐,所以也有了标题的「看这篇就够了」。TabLayout作为导航组件来说,使用场景非常的多,也意味着要满足各种各样的需求。在效果实现上&# 查看详情

handler原理剖析,看这篇就够了

Handler原理剖析,看这篇就够了本篇文章将会对Handler进行深层次的剖析,结合关系剖析图、代码走向剖析图以及10个常见问题,希望看完文章的同学都能有所收获,加深对Handler的了解!一、Handler运行原理剖析1.... 查看详情

图书管理系统设计与实现—看这篇就够了(代码片段)

图书管理系统设计与实现图书馆人员结构复杂,人员数量有限,涉及方面很广,如果还使用手工操作处理图书借阅问题,工作将非常繁琐,需要大量的人力、物理、财力,极大的浪费了资源,对于图书管理人员来说,图书馆管理... 查看详情

c++this指针----看这篇就够了(代码片段)

介绍在C++中,成员变量和成员函数是分开存储的,每一个非静态成员函数只会诞生一份函数实力,也就是说多个同类型的对象会共用这一个函数,那么当代码需要调用对象自己的时候,要怎么去区分那个... 查看详情

mongdb使用与原理看这篇就够了(代码片段)

什么是MongoDBmemory内存引擎,NoSQL最大的特点:1、默认支持分布式(内置分布式解决方案)2、高性能,高可用性和可伸缩性在NoSQL界,MongoDB是一个最像关系型数据库的非关系型数据库MongoDB应用场景适用范围... 查看详情

低功耗蓝牙ble传统广播总结—看这篇就够了

低功耗蓝牙:BluetoothLowEnergy简称BLE,相较于传统蓝牙BT具有低功耗、低成本、小体积等优势,BLE和BT都是工作在全世界公开通用的2.4GHz无线频段上,但他们是完全不同的两种技术,只是蓝牙技术联盟SIG将其归入蓝牙门类下,从而... 查看详情

博客园美化教程大集合(超详细,看这篇就够了)(代码片段)

阅读目录:  1. 前言  2.定制自己的博客0.美化整体效果1.准备工作2.自定义个性化导航栏3.添加顶部博主信息4.添加顶部滚动公告5.为博客文章添加目录导航6.添加分享功能按键7.定制推荐和反对按键的炫酷样式8.添加快速... 查看详情

java序列化,看这篇就够了(代码片段)

面试官:兄弟,说说你对transient的理解和感悟哪吒:what?还有感悟?先说结论,在序列化、反序列化时,被transient关键字修饰的成员属性变量不会被序列化。面试官:这就完了?哪吒:面试... 查看详情