Redis知识总结-0

之前我已经写过关于Redis的基本使用,Redis高可用这些文章,本篇只做总结。

Memcache:代码层次类似Hash
1.支持简单的数据类型。
2.不支持数据持久化存储。
3.不支持主从。
4.不支持分片。

Redis:
1.数据类型丰富。
2.支持数据磁盘持久化存储。
3.支持主从。
4.支持分片。

Redis非常快,官方提供的数据是100000+QPS。

  • Redis安全基于内存,绝大部分请求是纯粹的内存操作,执行效率高。

  • 数据结构简单,对数据操作也简单。

  • 采用单线程,单线程也能处理高并发请求,想多核也可以启动多实例。(避免了锁竞争和上下文资源的切换)

  • 使用多路I/O复用模型,非阻塞IO。

File Descriptor是文件描述符:一个打开的文件通过唯一的描述符进行引用,该描述符是打开文件的元数据到文件本身的映射。

传统阻塞I/O模型.png

Select系统调用,能同时监控多个文件的描述符的可读可写情况。当其中的一些文件描述符可读可写时,Select方法就会返回这些文件描述符的个数。

class java.nio.channels.Selector是Java的非阻塞I/O实现的关键。它使用了事件通知API以确定在一组非阻塞套接字中有哪些已经就绪能够进行I/O相关的操作。因为可以在任何的时间检查任意的读操作或者写操作的完成状态。与阻塞I/O模型相比,这种模型提供了更好的资源管理:

  • 1.使用较少的线程便可以处理许多连接,因此也减少了内存管理和上下文切换所带来的性能开销。
  • 2.当没有I/O操作需要处理的问题时,线程也可以被用于其他任务。
image.png

Redis采用的I/O多路复用函数:epoll/kqueue/evport/select?

  • 因地制宜,比如在linux环境下就采用epoll,在mac环境下就采用kqueue。
  • 优先选择时间复杂度为O(1)的I/O多路复用函数作为底层实现。
  • 以时间复杂度为O(n)的select作为保底。
  • 基于react设计模式监听I/O事件。

从海量Key里查询出某一固定前缀的Key,不能使用keys pattern,这样会造成redis卡顿阻塞。

我们可以通过SCAN cursor [MATCH pattern] [COUNT count]HSCAN key cursor [MATCH pattern] [COUNT count]:
1.基于游标的迭代器,需要基于上一次的游标延续之前的迭代过程。
2.以0作为游标开始一次新的迭代,直到命令返回游标0完成一次遍历。
3.不保证每次执行都返回某个给定数量的元素,支持模糊查询。
4.一次返回的数量不可控,只是大概率符合count参数。

如果使用Redis作为异步队列?可以使用List作为队列,RPUSH生成消息,LPOP消费消息。缺点就是LPOP不会等待队列有值才去消费的,可以通过在应用层引入Sleep机制去调用LPOP重试。也可以用BLPOP key[key...] timeout阻塞直到队列有消息或者超时。

pub/sub的缺点:消息的发布是无状态的,无法保证可达。


发布消息.png
接收消息.png
image.png

RDB(快照)持久化:保存某个时间点的全量数据快照。

备份进程出错的,那么主进程会终止写入操作,这是为了保护持久数据的一致性问题。

stop-writes-on-bgsave-error yes

Redis本身是一个CPU密集型的服务器,在开启压缩后会增大CPU的消耗。比起硬盘的成本,CPU更值钱。

rdbcompression yes

如果要禁用RDB策略

save ""

RDB文件可以通过2个命令来生成:
1.SAVE:阻塞Redis的服务器进程,直到RDB文件被创建完毕。


save.png

2.BGSAVE:Fork出一个子进程来创建RDB文件,不阻塞服务器进程。


image.png

自动化触发RDB持久化的方式:
1.根据redis.conf配置里面的save m n定时触发。(用的是bgsave)
2.主从复制时,从节点向主节点发送SYNC命令,主节点会进行持久化操作生成rdb文件。
3.执行Debug Reload命令

image.png

4.执行shutdown且没有开启AOF持久化。
image.png

BGSAVE原理图


image.png

系统调用fork():创建进程,实现了Copy-on-Write。传统方式下fork函数创建函数时把所有资源复制给子线程,这种效率低下,复制的资源有可能对子线程毫无用处。linux改进了fork的实现方式,当父进程创建子进程时,内核会对子进程程创建虚拟空间,父子两个进程用的是同一块物理空间。只有父进程发生更改时,才会为子进程分配独立的物理空间。

Copy-on-Write的定义:
如果有多个调用者同时要求相同资源(如内存或磁盘上的数据存储),他们会共同获取相同的指针指向相同的资源,直到某个调用者试图修改资源的内容时,系统才会真正复制一份专用副本给该调用者,而其他调用者所见到的最初的资源仍然保持不变。

当Redis需要做持久化时,会fork一个子进程,子进程将数据写到磁盘上的一个临时RDB文件中。当子进程完成写入临时文件后,会将原来的RDB文件替换掉。这样做的好处是可以实现Copy-On-Write,确保了Redis的性能。

RDB持久化的缺点:
1.内存数据的全量同步,数据量大会由于I/O而严重影响性能。
2.可能会因为Redis挂掉而丢失从当前至最近一次快照期间的数据。

AOF(Append-Only-File)持久化:保存写状态。

  • 记录下除了查询以外的所有变更数据库状态的指令。

  • 以append的形式追加保存到AOF文件中(增量)。

日志重写解决AOF文件大小不断增大的问题,原理如下:
1.调用fork(),创建一个子进程。
2.子进程把新的AOF写到一个临时文件里,不依赖原来的AOF文件。
3.主进程持续将新的变动写到内存和原来的AOF里。
4.主进程获取子进程重写AOF的完成信号,往新AOF同步增量变动。
5.使用新的AOF文件替换掉旧的AOF文件。

RDB-AOF混合持久化方式:

  • BGSAVE做镜像全量持久化,AOF做增量持久化。


    image.png

Pipeline和linux的管道有点类似。Redis基于请求/响应模型,单个请求处理需要一一应答。Pipeline批量执行指令,节省多次IO往返的时间。如果指令有顺序依赖的指令建议分批发送。

流言协议Gossip在杂乱无章中寻求一致:
1.每个节点都随机的与对方通信,最终所有节点的状态达成一致。
2.种子节点定期随机向其他节点发送节点列表以及需要传播的消息。
3.不保证信息一定会传递给所有节点,但是最终会趋于一致。

如何从海量数据里快速找到所需要的数据?

  • 分片:按照某种规则去划分数据,分散存储在多个节点上。
  • 常规的按照哈希划分无法实现节点的动态增减,会造成缓存失效的现象。

所以引入了一致性哈希算法,这里是将2^32取模,将哈希值空间组织成虚拟的圆环。本文参照一致性哈希算法原理

1.假设某哈希函数H的值空间为0-2^32 - 1,整个空间按顺时针方向组织。0和2^32-1在零点中方向重合。

image.png

2.可以选择将服务器的ip或者主机名作为关键字进行hash,这些每台机器就能确定其在哈希环上的位置。

image.png

3.将数据的key使用相同的函数进行hash,确认此数据在环上的位置,从此位置沿环顺时针行走,第一台遇到的服务器就是其应该定位到的服务器。

image.png

4.一致性哈希算法具有容错性和可扩展性,假设节点C宕机了,可以看到此时对象A、B、D都不会被影响,只有C对象被重新定位到节点D。如果在系统中增加一台服务器X,此时对象A、B、D不受影响,只有对象C需要重新定位到新的节点X上。

image.png

5.一致性哈希算法在服务节点太少时,容易因为节点分布不均匀而造成数据倾斜问题。假如系统中有2台服务器,必然造成大量数据集中到节点A上,而只有极少量会定位到节点B上。


image.png

6.为了解决这种数据倾斜问题,一致性哈希算法引入了虚拟节点机制,即对每一个服务节点计算多个hash,每个计算结果位置都放置一个此服务器节点,称为虚拟节点。具体做法可以在服务器ip或者主机名的后面增加编号来实现。

image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容

  • 1.1 资料 ,最好的入门小册子,可以先于一切文档之前看,免费。 作者Antirez的博客,Antirez维护的R...
    JefferyLcm阅读 17,030评论 1 51
  • 前言 在上一篇文章中,介绍了Redis内存模型,从这篇文章开始,将依次介绍Redis高可用相关的知识——持久化、复...
    Java架构阅读 2,292评论 3 21
  • 一、Redis高可用概述 在介绍Redis高可用之前,先说明一下在Redis的语境中高可用的含义。 我们知道,在w...
    空语阅读 1,593评论 0 2
  • 企业级redis集群架构的特点 海量数据 高并发 高可用 要达到高可用,持久化是不可减少的,持久化主要是做灾难恢复...
    lucode阅读 2,192评论 0 7
  • 原帖地址:https://www.jianshu.com/p/2f14bc570563 redis概述 Redis...
    onlyHalfSoul阅读 2,154评论 0 28