导航:首页 > 净水问答 > redis数据过滤

redis数据过滤

发布时间:2022-09-27 18:51:26

① redis sentinel 哨兵,看这一篇就够啦!

    redis集群模式,丢失master主服务器是无法继续工作的,所以随时都需要一个master节点。但是服务器宕机是经常出现的事情,集群本身是无法完成故障转移的,所以需要一个第三方的解决方案,帮redis集群完成故障转移(选择主节点、通知从节点修改同步master地址,让原来的主节点成为从节点)。

(1)首先sentinel也属于一种redis服务器,只不过启动时加载的配置文件不同。配置文件里包括了监控的主服务器列表(对,可以是多个主服务器,即就是多个集群)。

(2)sentinel通过配置文件中的主服务器IP:端口号,建立链接和订阅,就是一个双向的通道

(3)sentinel默认每10秒,向建立链接的主服务器,发送INFO命令;主服务器收到命令,返回主服务器信息。

可以看到,返回了主服务器的运行ID,重要的是:同步主服务器的从节点信息

(4)从步骤(3)中获取到的从节点信息,从节点的IP和端口。sentinel和从节点建立链接和订阅

(5)sentinel默认每10秒,向建立链接的从服务器,发送INFO命令,从服务器接收到命令后,返回从服务器信息

    主要包括了从服务器对应的master节点的地址:端口号,偏移量

(6)sentinel与主服务器和从服务器建立了链接和订阅,可以向主从服务器发送命令,也可以接收主从服务器的广播

订阅命令:subscribe _sentinel_:hello

通道名:hello

sentinel对hello频道的订阅会一直持续到sentinel和服务器之间的链接断开为止

sentinel向服务器通道发送的消息,其他与该服务器建立订阅关系的sentinel也会收到订阅通知,sentinel自己也会收到自己发出的消息的订阅通知

(7)sentinel默认会每两秒一次,向所有建立链接和订阅的主从服务器,发送广播消息

命令:publish_sentinel__:hello  "<s_ip>,<s_port>,<s_runid>,<s_epoch>,<m_name>,<m_ip>,<m_port>,<m_epoch>"

可以看到主要包含
s_ip : sentinel自己 IP地址

s_port : sentinel自己端口号

s_runid : sentinel自己的运行ID

s_epoch : sentinel当前的配置纪元

m_name, m_ip, m_port, m_epoch : 当前监控服务器的名称(主或者从)、IP地址、端口号、当前配置纪元

这个消息,也会被其他订阅该通道的sentinel收到

sentinel在接收到订阅消息后(就是上文中自己与别的sentinel,publish的消息),首先过滤掉自己发,然后接收别人的消息,就能获取监听改主服务器的所有sentinel节点

(8)通过上一步,sentinel能够感知到其他监控主服务器的sentinel节点,然后和其他sentinel建立连接,最终,所有监视主服务器的sentinel节点组成了一个相关连接的网络!

sentinel会默认每1s向自己所建立连接的服务器发送PING命令,这些服务器包括(监视master的其他sentinel,master、salve服务器),根据收到的返回值,来确定目标服务器的状态

常见返回值:+PONG、-LOADING、-MASTERDOWN,含义在此处先不关注

判定条件:目标服务器在一定的时间内(配置文件字段:down-after-milliseconds的值),一直返回“失败”

对失败的定义:

(1)目标服务器没有在规定时间内返回(该时间可配置)

(2)目标服务器返回了上述三种返回值之外的值

确定一个目标服务器失败之后,会在sentinel自己的实例表中记录该实例的状态,用:

SRI_S_DOWN表示,S=subjective客观

注:一个master服务器会被多个sentinel监控,多个sentinel可能设置了不同的

down-after-milliseconds

        和我们设想的一样,单一的sentinel并不能决定目标master服务器的生死存亡,会拿着自己实例表里的“客观”下线的服务器地址和端口,去向同样监控这台服务器的sentinel询问,看看“别人”这个服务器到底下线没? 当能够从别的sentinel那里询问到“足够数量”的已下线(客观下线或者主观下线)结果后,sentinel就可以判断目标服务器真的下线了,就可以执行故障转移了。

(1)sentinel发送命令is-master-down-by-addr

SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <runid>

发送的目标:监控master服务器的其他sentinel

参数解析:ip、port=自己监控的master服务器的IP,端口,current_epoch=源sentinel当前的配置纪元,runid=源sentinel的唯一标识ID

(2)sentinel对命令is-master-dowm-by-addr的回复

        1) <down_state> :下线的状态,0-未下线,1-已下线

        2) <leader_runid> :当前sentinel的局部leader,为 “*” 时表示没有leader

        3) <leader_epoch> :当前sentinel的局部leader的配置纪元,当没有leader时,该项为0

(3)sentinel收到命令is-master-down-by-addr的回复后

        sentinel收到足够数量(可配置)的“已下线”回复(即down_state=1),就会在自己的实例表里将对应的master服务器状态(flags)设置为 SRI_O_DOWN,O=Objective。

        监控同一个master服务器的sentinel,对客观下线的条件可以不一致,即收到多少已下线回复才认定客观下线,可以不尽相同。

        由于监控同一个master服务器的sentinel有很多,并不能决定是哪个sentinel去执行故障转移,所以需要多个sentinel进行选leader头结点。

        具体步骤:

        (1)sentinel通过向其他sentinel节点发送is-master-down-by-addr命令,已经可以判断当前master服务器是否客观下线

     (2)已经判断master服务器客观下线的sentinel,再次向其他节点发送
is-master-down-by-addr命令,携带自己的runId和配置纪元

这里再复习一遍命令 :
sentinel is-master-down-by-addr <ip>,<port>,<cur_epoch>,<runid>

    (3)目标sentinel收到源sentinel的 is-master…命令之后,执行以下判断

            1>判断epoch和自己的纪元是否相等,不相等直接舍弃这条命令

            2>判断自己的配置表里是否有局部leader,没有的话,将源sentinel的runid设置为自己的局部了leader

                如果已经有了局部leader,那么会返回自己的局部leader的信息

            3>对源sentinel的is-master-down-by-addr命令进行回复

示例:
        源sentinel向目标sentinel发送命令,
                 SENTINEL is-master-down-by-addr 127.0.0.1 8080 0 11522852334a

        源sentinel收到命令的回复

                1    

                11522852334a

                0

        表示有一个sentinel将自己成功设置成为leader(需要把返回的runid和自己的runid比对)

            4>当过半的sentinel将自己成功设置为局部leader,标识选主成功,如果在一段时间内没有收到过半的成功数,那么会进行下一轮命令的发送,epoch递增+1

                例如,共有10个sentinel监视同一个master服务器,其中一个sentinel必须收到10/2+1=6个及以上的成功数,才能认为自己成功当选leader

(1)筛选master节点的备胎(即就是哪些slave节点可以成为新的master)

          选择master节点备胎就一个要求,数据尽量完整,状态尽量好

            1>删除,客观下线或者主观下线的slave服务器

            2>删除,在最近5s没有回复过头sentinel节点的INFO命令的slave服务器

            剩下的slave服务器,根据优先级进行排序,遇到优先级一样的,再根据偏移量排序(目的是筛选出和master服务器数据较同步的slave服务器)。再遇到偏移量一样的,继续根据runid排序,找出runid最小的(没有什么依据,只是个排序),至此,可以作为master的slave服务器就筛选好了。

    (2)slave服务器升级为master

            头sentinel向步骤(1)中筛选出来的slave服务器发送slaveof_no_one,发送完该转移命令。之后,头sentinel每秒一次的频率向上述slave服务器发送INFO命令,观察INFO命令返回的role字段,看是否变为master,变为master表示成功升级为master服务器。

   (3)修改原slave服务器列表的复制/同步目标

            头sentinel向原slave服务器列表发送命令:

slave of 127.0.0.1:8080,修改slave的复制目标

   (4)修改已下线的master服务器为新master的slave节点

            头sentinel保持对已下线master的监控,当已下线master重新上线(对PING命令有回复),就对他发送slave of 127.0.0.1命令,让其成为slave。

            至此,故障转移全部结束。

② rediserach有大公司用吗

你好,问的是redisearch吧。不知道你指的大公司是什么,但是现在还蛮多人在用的。
RediSearch是一个高性能的全文搜索引擎,可作为一个RedisMole运行在Redis上,是由RedisLabs团队开发的。特点是:Faster,in-memory,highlyavailablefulltextsearch。
RediSearch是在Redis基础上从0开始开发的一个全文搜索索引,使用新的RedisMolesAPI来扩展Redis新命令和能力,它的主要特性包括:
简单,快速索引和搜索
数据存储在内存中,使用内存-有效的自定义数据结构
支持多种使用UTF-8编码的语言
文档和字段评分
结果的数值过滤
通过词干扩展查询
精确的短语搜索
按特定属性过滤结果(例如仅在标题中搜索“foo”
强大的自动提示引擎
增量索引(不需要对索引进行优化和压缩)
支持用作存储在另一数据库中的文档的搜索索引
支持已经在Redis中存在的HASH对象作为文件的索引
扩展到多个Redis实例

③ 布隆过滤器

[TOC]

通过解决方案:

Java中如将数据存储在内存中,最简单的算法结构是HashMap。通过HashMap判断key是否存在,来判断数据是否存在。通过hash算法查找元素,时间复杂度基本是 O(1) (可能存在hash冲突后转换成链表或红黑树的情况,时间复杂度的影响可以忽略)。

使用HashMap速度很快,存储简单,绝大部分场景可以使用。但是HashMap 占用的空间比较大 :

为什么出现布隆过滤器:

举例:

如1000万个Integer存储在内存中,占用空间为:4x32x10000000位,即1220兆。如布隆过滤器通过4字节存储(布隆过滤器通过多次hash对数据计算后-->几次hash根据数据量指定,得到多个数据, 占用多个位 ),则占用空间为610M。比原有空间少一半。

个人觉得,此比较在字符等的比较中尤为有效。
一个字符串多个字符,根据编码方式,一个字符两个或三个字节,如10个字符,字符串存储占用20个字节,还有相关字符串相关的类信息的内存占用。
位存储,根据数据量的大小,hash的位数,灵活计算。如4个字节,则是原hashMap占用空间的五分之一。

(1)定义字节向量

先定义一个指定长度的字节数组(字节数组,数组内每个元素的值)。

如长度为8(一个字节大小),默认所有元素值均为0,如下:

(2)计算哈希值

将要写入过滤器的数据,根据一定数量的哈希函数,得到多个哈希值,再依次判断每个哈希值对应的索引。

如使用3个哈希函数,计算得到3个哈希值,判定哈希值对应的字节向量为为1,3,7。

(3)更新字节向量

将计算出的字节向量的索引, 对应的字节向量中的元素值更高为1 (无论之前为0或者为1,均更改为1)。如下:

(1)计算哈希值

将要判断过滤器中是否存在的数据,根据一定数量的哈希函数,得到多个哈希值,再依次判断每个哈希值对应的索引。

如使用3个哈希函数,计算得到3个哈希值,判定哈希值对应的字节向量为为1,3,7。

注意:哈希函数的判断方式和计算索引的方式,需和写入数据时完全一致。

(2)判断是否存在

如原字节数组中,对应1,3,7中存在的元素的值都为1。则判定为此元素 可能存在 ,但凡有一个元素的值不为1,则判定此元素 一定不存在 。

布隆过滤器,主要需实现的目标是, 在指定的数据个数范围内,满足误判率在设定的范围内 ,误判率太高的话,无法起到过滤数据的情况,误判率不能为0。

因此需要计算两个数据来满足 存储数据的个数 和 误判率 :

使用布隆过滤器的决定性因素之一,就是此算法插入数据和查询数据的速度必须非常快。因此在对数据进行哈希运算的时候, 需选择计算快的哈希算法 。

而且, 写入数据以及查询数据的哈希算法,顺序和算法都需完全一致 。

待完善。。。。。

可以通过google的 guava ,在内存中轻松实现布隆过滤器。

无需手动计算满足字节数组的长度和哈希个数,只需要输入 拟输入数据的个数 和 期望误判率 即可。

不输入期望误判率的情况下,误判率为0.03,即100个非范围内的数据进行校验时,约三个数据会判定为存在。

多次执行,结果一致,根据结果判定:

内存的存储存在局限性,可以使用redis中的bitMap来实现字节数组的存储。

使用redis实现布隆过滤器。需要根据公式,手动计算字节数组的长度和哈希的个数。

实现过程,待完善。。。。。。

④ 布隆过滤器详解

布隆过滤器 (英语:Bloom Filter)是 1970 年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。主要用于判断一个元素是否在一个集合中。

通常我们会遇到很多要判断一个元素是否在某个集合中的业务场景,一般想到的是将集合中所有元素保存起来,然后通过比较确定。链表、树、散列表(又叫哈希表,Hash table)等等数据结构都是这种思路。但是随着集合中元素的增加,我们需要的存储空间也会呈现线性增长,最终达到瓶颈。同时检索速度也越来越慢,上述三种结构的检索时间复杂度分别为 , , 。

这个时候,布隆过滤器(Bloom Filter)就应运而生。

了解布隆过滤器原理之前,先回顾下 Hash 函数原理。

哈希函数的概念是:将任意大小的输入数据转换成特定大小的输出数据的函数,转换后的数据称为哈希值或哈希编码,也叫散列值。下面是一幅示意图:

所有散列函数都有如下基本特性:

但是用 hash表存储大数据量时,空间效率还是很低,当只有一个 hash 函数时,还很容易发生哈希碰撞。

BloomFilter 是由一个固定大小的二进制向量或者位图(bitmap)和一系列映射函数组成的。

在初始状态时,对于长度为 m 的位数组,它的所有位都被置为0,如下图所示:

当有变量被加入集合时,通过 K 个映射函数将这个变量映射成位图中的 K 个点,把它们置为 1(假定有两个变量都通过 3 个映射函数)。

查询某个变量的时候我们只要看看这些点是不是都是 1 就可以大概率知道集合中有没有它了

为什么说是可能存在,而不是一定存在呢?那是因为映射函数本身就是散列函数,散列函数是会有碰撞的。

布隆过滤器的误判是指多个输入经过哈希之后在相同的bit位置1了,这样就无法判断究竟是哪个输入产生的,因此误判的根源在于相同的 bit 位被多次映射且置 1。

这种情况也造成了布隆过滤器的删除问题,因为布隆过滤器的每一个 bit 并不是独占的,很有可能多个元素共享了某一位。如果我们直接删除这一位的话,会影响其他的元素。(比如上图中的第 3 位)

相比于其它的数据结构,布隆过滤器在空间和时间方面都有巨大的优势。布隆过滤器存储空间和插入/查询时间都是常数 ,另外,散列函数相互之间没有关系,方便由硬件并行实现。布隆过滤器不需要存储元素本身,在某些对保密要求非常严格的场合有优势。

布隆过滤器可以表示全集,其它任何数据结构都不能;

但是布隆过滤器的缺点和优点一样明显。误算率是其中之一。随着存入的元素数量增加,误算率随之增加。但是如果元素数量太少,则使用散列表足矣。

另外,一般情况下不能从布隆过滤器中删除元素。我们很容易想到把位数组变成整数数组,每插入一个元素相应的计数器加 1, 这样删除元素时将计数器减掉就可以了。然而要保证安全地删除元素并非如此简单。首先我们必须保证删除的元素的确在布隆过滤器里面。这一点单凭这个过滤器是无法保证的。另外计数器回绕也会造成问题。

在降低误算率方面,有不少工作,使得出现了很多布隆过滤器的变种。

在程序的世界中,布隆过滤器是程序员的一把利器,利用它可以快速地解决项目中一些比较棘手的问题。

如网页 URL 去重、垃圾邮件识别、大集合中重复元素的判断和缓存穿透等问题。

布隆过滤器的典型应用有:

知道了布隆过滤去的原理和使用场景,我们可以自己实现一个简单的布隆过滤器

分布式环境中,布隆过滤器肯定还需要考虑是可以共享的资源,这时候我们会想到 Redis,是的,Redis 也实现了布隆过滤器。

当然我们也可以把布隆过滤器通过 bloomFilter.writeTo() 写入一个文件,放入OSS、S3这类对象存储中。

Redis 提供的 bitMap 可以实现布隆过滤器,但是需要自己设计映射函数和一些细节,这和我们自定义没啥区别。

Redis 官方提供的布隆过滤器到了 Redis 4.0 提供了插件功能之后才正式登场。布隆过滤器作为一个插件加载到 Redis Server 中,给 Redis 提供了强大的布隆去重功能。

在已安装 Redis 的前提下,安装 RedisBloom,有两种方式

直接编译进行安装

使用Docker进行安装

使用

布隆过滤器基本指令:

我们只有这几个参数,肯定不会有误判,当元素逐渐增多时,就会有一定的误判了,这里就不做这个实验了。

上面使用的布隆过滤器只是默认参数的布隆过滤器,它在我们第一次 add 的时候自动创建。

Redis 还提供了自定义参数的布隆过滤器, bf.reserve 过滤器名 error_rate initial_size

但是这个操作需要在 add 之前显式创建。如果对应的 key 已经存在,bf.reserve 会报错

我是一名 Javaer,肯定还要用 Java 来实现的,Java 的 Redis 客户端比较多,有些还没有提供指令扩展机制,笔者已知的 Redisson 和 lettuce 是可以使用布隆过滤器的,我们这里用 Redisson

为了解决布隆过滤器不能删除元素的问题,布谷鸟过滤器横空出世。论文《Cuckoo Filter:Better Than Bloom》作者将布谷鸟过滤器和布隆过滤器进行了深入的对比。相比布谷鸟过滤器而言布隆过滤器有以下不足:查询性能弱、空间利用效率低、不支持反向操作(删除)以及不支持计数。

由于使用较少,暂不深入。

https://www.cs.cmu.e/~dga/papers/cuckoo-conext2014.pdf

http://www.justdojava.com/2019/10/22/bloomfilter/

https://www.cnblogs.com/cpselvis/p/6265825.html

https://juejin.im/post/5cc5aa7ce51d456e431adac5

⑤ redis主从和哨兵

主从复制:主节点负责写数据,从节点负责读数据,主节点定期把数据同步到从节点保证数据的一致性

a,配置主从复制方式一、新增redis6380.conf, 加入 slaveof 192.168.152.128 6379, 在6379启动完后再启6380,完成配置;
b,配置主从复制方式二、redis-server --slaveof 192.168.152.128 6379 临时生效

c,查看状态:info replication
d,断开主从复制:在slave节点,执行6380:>slaveof no one
e,断开后再变成主从复制:6380:> slaveof 192.168.152.128 6379
f,数据较重要的节点,主从复制时使用密码验证: requirepass
e, 从节点建议用只读模式slave-read-only=yes, 若从节点修改数据,主从数据不一致
h,传输延迟:主从一般部署在不同机器上,复制时存在网络延时问题,redis提供repl-disable-tcp-nodelay参数决定是否关闭TCP_NODELAY,默认为关闭
参数关闭时:无论大小都会及时发布到从节点,占带宽,适用于主从网络好的场景,
参数启用时:主节点合并所有数据成TCP包节省带宽,默认为40毫秒发一次,取决于内核,主从的同步延迟40毫秒,适用于网络环境复杂或带宽紧张,如跨机房

a)一主一从:用于主节点故障转移从节点,当主节点的“写”命令并发高且需要持久化,可以只在从节点开启AOF(主节点不需要),这样即保证了数据的安全性,也避免持久化对主节点的影响

b)一主多从:针对“读”较多的场景,“读”由多个从节点来分担,但节点越多,主节点同步到多节点的次数也越多,影响带宽,也加重主节点的稳定

c)树状主从:一主多从的缺点(主节点推送次数多压力大)可用些方案解决,主节点只推送一次数据到从节点B,再由从节点B推送到C,减轻主节点推送的压力。

redis 2.8版本以上使用psync命令完成同步,过程分“全量”与“部分”复制
全量复制:一般用于初次复制场景(第一次建立SLAVE后全量)
部分复制:网络出现问题,从节点再次连接主节点时,主节点补发缺少的数据,每次数据增量同步
心跳:主从有长连接心跳,主节点默认每10S向从节点发ping命令,repl-ping-slave-period控制发送频率

a)主从复制,若主节点出现问题,则不能提供服务,需要人工修改配置将从变主
b)主从复制主节点的写能力单机,能力有限
c)单机节点的存储能力也有限

a)主节点(master)故障,从节点slave-1端执行 slaveof no one后变成新主节点;
b)其它的节点成为新主节点的从节点,并从新节点复制数据;
c)需要人工干预,无法实现高可用。

1. 为什么要有哨兵机制?

原理:当主节点出现故障时,由Redis Sentinel自动完成故障发现和转移,并通知应用方,实现高可用性。

其实整个过程只需要一个哨兵节点来完成,首先使用Raft算法(选举算法)实现选举机制,选出一个哨兵节点来完成转移和通知

任务1:每个哨兵节点每10秒会向主节点和从节点发送info命令获取最拓扑结构图,哨兵配置时只要配置对主节点的监控即可,通过向主节点发送info,获取从节点的信息,并当有新的从节点加入时可以马上感知到

任务2:每个哨兵节点每隔2秒会向redis数据节点的指定频道上发送该哨兵节点对于主节点的判断以及当前哨兵节点的信息,同时每个哨兵节点也会订阅该频道,来了解其它哨兵节点的信息及对主节点的判断,其实就是通过消息publish和subscribe来完成的

任务3:每隔1秒每个哨兵会向主节点、从节点及其余哨兵节点发送一次ping命令做一次心跳检测,这个也是哨兵用来判断节点是否正常的重要依据

客观下线:当主观下线的节点是主节点时,此时该哨兵3节点会通过指令sentinel is-masterdown-by-addr寻求其它哨兵节点对主节点的判断,当超过quorum(选举)个数,此时哨兵节点则认为该主节点确实有问题,这样就客观下线了,大部分哨兵节点都同意下线操作,也就说是客观下线

a)每个在线的哨兵节点都可以成为领导者,当它确认(比如哨兵3)主节点下线时,会向其它哨兵发is-master-down-by-addr命令,征求判断并要求将自己设置为领导者,由领导者处理故障转移;
b)当其它哨兵收到此命令时,可以同意或者拒绝它成为领导者;
c)如果哨兵3发现自己在选举的票数大于等于num(sentinels)/2+1时,将成为领导者,如果没有超过,继续选举…………

a)由Sentinel节点定期监控发现主节点是否出现了故障

sentinel会向master发送心跳PING来确认master是否存活,如果master在“一定时间范围”内不回应PONG 或者是回复了一个错误消息,那么这个sentinel会主观地(单方面地)认为这个master已经不可用了

b) 当主节点出现故障,此时3个Sentinel节点共同选举了Sentinel3节点为领导,负载处理主节点的故障转移

c) 由Sentinel3领导者节点执行故障转移,过程和主从复制一样,但是自动执行

流程:

1. 将slave-1脱离原从节点,升级主节点,

d) 故障转移后的redis sentinel的拓扑结构图

a) 过滤掉不健康的(下线或断线),没有回复过哨兵ping响应的从节点

b) 选择salve-priority从节点优先级最高(redis.conf)的

c) 选择复制偏移量最大,指复制最完整的从节点

以3个Sentinel节点、2个从节点、1个主节点为例进行安装部署

1. 前提: 先搭好一主两从redis的主从复制,和之前的主从复制搭建一样,搭建方式如下:

A)主节点6379节点(/usr/local/bin/conf/redis6379.conf):

修改 requirepass 12345678,注释掉#bind 127.0.0.1

B) 从节点redis6380.conf和redis6381.conf: 配置都一样

修改 requirepass 12345678 ,注释掉#bind 127.0.0.1,

加上访问主节点的密码masterauth 12345678 ,加上slaveof 192.168.152.128 6379

2. redis sentinel哨兵机制核心配置 (也是3个节点):

将三个文件的端口改成: 26379 26380 26381

然后:sentinel monitor mymaster 192.168.152.128 6379 2 //监听主节点6379

三个配置除端口外,其它一样。

3. 哨兵其它的配置 :只要修改每个sentinel.conf的这段配置即可:

sentinel monitor mymaster 192.168.152.128 6379 2

//监控主节点的IP地址端口,sentinel监控的master的名字叫做mymaster,2代表,当集群中有2个sentinel认为master死了时,才能真正认为该master已经不可用了

sentinel auth-pass mymaster 12345678 //sentinel连主节点的密码

sentinel config-epoch mymaster 2 //故障转移时最多可以有2从节点同时对新主节点进行数据同步

sentinel leader-epoch mymaster 2

sentinel failover-timeout mymasterA **180000 **//故障转移超时时间180s,

a,如果转移超时失败,下次转移时时间为之前的2倍;

b,从节点变主节点时,从节点执行slaveof no one命令一直失败的话,当时间超过 180S 时,则故障转移失败

c,从节点复制新主节点时间超过 180S 转移失败

sentinel down-after-milliseconds mymasterA 300000 //sentinel节点定期向主节点ping命令,当超过了 300S 时间后没有回复,可能就认定为此主节点出现故障了……

sentinel parallel-syncs mymasterA 1 //故障转移后, 1 代表每个从节点按顺序排队一个一个复制主节点数据,如果为3,指3个从节点同时并发复制主节点数据,不会影响阻塞,但存在网络和IO开销

4. 启动redis服务和sentinel服务:

a)先把之前安装的redis里面的标绿色的文件都拷贝到 usr/local/bin目录下,然后再再bin目录下新建一个conf文件夹存放配置好的redis主从配置文件和哨兵配置文件

b)启动主从复制服务,先启动主再启动从

主:./redis-server conf/redis6379.conf &

从:

./redis-server conf/redis6380.conf &

./redis-server conf/redis6381.conf &

c)启动sentinel服务:

./redis-sentinel conf/sentinel_26381.conf &

到此服务全部启动完毕

连接到6379的redis的服务,可看到6379就是主节点,他有6380和6381两个从节点

5. 测试: kill -9 6379 杀掉6379的redis服务

可以看到杀掉6379以后6380变为了主节点,6381变为了6380的从节点

重新启动6379以后变为6380的从节点

看日志是分配6380 是6381的主节点,当6379服务再启动时,已变成从节点

假设6380升级为主节点:进入6380>info replication 可以看到role:master

打开sentinel_26379.conf等三个配置,sentinel monitor mymaster 192.168.152.128 6380 2

打开redis6379.conf等三个配置, slaveof 192.168.152.128 6380,也变成了6380

注意:生产环境建议让redis Sentinel部署到不同的物理机上。

a,sentinel节点应部署在多台物理机(线上环境)

b,至少三个且奇数个sentinel节点

c,通过以上我们知道,3个sentinel可同时监控一个主节点或多个主节点

sentinel参考资料:
redis sentinel的机制与用法一: https://segmentfault.com/a/1190000002680804

redis sentinel的机制与用法二: https://segmentfault.com/a/1190000002685515

⑥ 怎样基于Redis实现模糊查询

模糊查询不是这类数据库的强项。如果一定要这样查询,可以使用Rula写过程来查询,或把数据取到内存再写程序代码过滤。服务本身并没有提供模糊查询的功能。

⑦ Redis哨兵机制原理浅析

上一篇文章Redis主从复制原理中简要地说明了主从复制的一个基本原理,包含全量复制、复制积压缓冲区与增量复制等内容,有兴趣的同学可以先看下。

利用主从复制,可以实现读写分离、数据备份等功能。但如果主库宕机后,需要运维人员手动地将一个从库提升为新主库,并将其他从库slaveof新主库,以此来实现故障恢复。

因此, 主从模式的一个缺点,就在于无法实现自动化地故障恢复 。Redis后来引入了哨兵机制,哨兵机制大大提升了系统的高可用性。

哨兵,就是站岗放哨的,时刻监控周围的一举一动,在第一时间发现敌情并发出及时的警报。

Redis中的哨兵(Sentinel), 则是一个特殊的Redis实例 ,不过它并不存储数据。也就是说,哨兵在启动时,不会去加载RDB文件。

关于Redis的持久化,可以参考我的另外一篇文章 谈谈Redis的持久化——AOF日志与RDB快照

上图就是一个典型的哨兵架构,由数据节点与哨兵节点构成,通常会部署多个哨兵节点。

哨兵主要具有三个作用, 监控、选主与通知

监控:哨兵会利用心跳机制,周期性不断地检测主库与从库的存活性

选主:哨兵检测到主库宕机后,选择一个从库将之切换为新主库

通知:哨兵会将新主库的地址通知到所有从库,使得所有从库与旧主库slaveof新主库,也会将新主库的地址通知到客户端上

我会在下文详细讲一下监控与选主的过程

哨兵系统是通过3个定时任务,来完成对主库、从库与哨兵之间的探活。

首先我们会在配置文件中配置主库地址,这样哨兵在启动后,会以 每隔10秒 的频率向主库发送info命令,从而获得当前的主从拓扑关系,这样就拿到了所有从库的地址。

接着 每隔2秒 ,会使用pub/sub(发布订阅)机制,在主库上的 sentinel :hello的频道上发布消息,消息内容包括哨兵自己的ip、port、runid与主库的配置。

每个哨兵都会订阅该频道,在该频道上发布与消费消息,从而实现哨兵之间的互相感知。

利用启动配置与info命令可以获取到主从库地址,利用发布订阅可以感知到其余的哨兵节点。

在此基础上,哨兵会 每隔1秒 向主库、从库与其他哨兵节点发送PING命令,因此来进行互相探活。

当某个哨兵在 **down-after-milliseconds(默认是30秒) **配置的连续时间内,仍然没有收到主库的正确响应,则当前哨兵会认为主库 主观下线 ,并将其标记为sdown(subjective down)

为了避免当前哨兵对主库的误判,因此这个时候还需要参考其他哨兵的意见。

接着当前哨兵会向其他哨兵发送 sentinel is-master-down-by-addr 命令, 如果有半数以上(由quorum参数决定)的哨兵认为主库确实处于主观下线状态,则当前哨兵认为主库客观下线 ,标记为odown(objective down)

一旦某个主库被认定为客观下线时,这个时候需要进行哨兵选举,选举出一个领导者哨兵,来完成主从切换的过程。

哨兵A在向其他哨兵发送 sentinel is-master-down-by-addr 命令时,同时要求其他哨兵同意将其设置为Leader,也就是想获得其他哨兵的投票。

在每一轮选举中,每个哨兵仅有一票。投票遵循先来先到的原则,如果某个哨兵没有投给别人,就会投给哨兵A。

首先获得半数以上投票的哨兵,将被选举称为Leader。

这里的哨兵选举,采用的是Raft算法。这里不对Raft做详细的探讨,有兴趣的同学,可以参考我的另外一篇文章 22张图,带你入门分布式一致性算法Raft

该文章采用大量的图例,相信你可以从中学习到全新的知识,从而打开分布式一致性算法的大门,大伙们记得等我搞完Paxos与Zab。

过半投票机制也常用于很多算法中,例如RedLock,在半数以上的节点上加锁成功,才代表申请到了分布式锁,具体可参考这篇文章的最后 我用了上万字,走了一遍Redis实现分布式锁的坎坷之路,从单机到主从再到多实例,原来会发生这么多的问题

在Zookeeper选举中,同样也用到了过半投票机制,在这篇文章中 面试官:能给我画个Zookeeper选举的图吗? 我从源码角度分析了Zookeeper选举的过程。

在选举到领导者哨兵后,将由该哨兵完成故障恢复工作。

故障恢复分为以下两步:

详细说一下第一步,挑选是有条件的。首先要过滤出不健康的节点,再按某种规则排序,最后取第一个从库,我们直接从源码入手:

因此,以下从库会被过滤出:

剩下的节点,就是健康的节点,此时再执行一次快速排序,排序的规则如下:

本文算是Redis哨兵的一个入门文章,主要讲了哨兵的作用,例如监控、选主和通知。

在Redis读写分离的情况下,使用哨兵可以很轻松地做到故障恢复,提升了整体的可用性。

但哨兵无法解决Redis单机写的瓶颈,这就需要引入集群模式,相应的文章也被列为明年的写作计划中。

</article>

⑧ 借助Redis Bitmap实现简单的布隆过滤器

在之前的 一篇文章 中,我们已经深入理解了布隆过滤器的基本原理,并且了解到它在缓存系统中有较多的应用。Redis提供的Bitmap正好能够作为布隆过滤器所需要的位数组的基础,本文先简要介绍Bitmap,然后给出基于它的布隆过滤器实现。

Bitmap在Redis中并不是一个单独的数据类型,而是由字符串类型(Redis内部称Simple Dynamic String,SDS)之上定义的与比特相关的操作实现的,此时SDS就被当做位数组了。下面是在redis-cli中使用getbit和setbit指令的操作示例。

Redis的Bitmap是自动扩容的,亦即get/set到高位时,就会主动填充0。此外,还有bitcount指令用于计算特定字节范围内1的个数,bitop指令用来执行位运算(支持and、or、xor和not)。相应的用法可以查询Redis官方文档等。

下面我们基于Redis(Codis)实现布隆过滤器RedisBloomFilter。根据之前讲解布隆过滤器的文章,要初始化一个布隆过滤器的话,需要两个参数:预估的元素数量,以及可接受的最大误差(即假阳性率)。另外,我们也需要传入Jodis的连接池实例JedisResourcePool,以方便在Redis上操作。RedisBloomFilter类的成员和构造方法如下所示。

为了区分出布隆过滤器对应的Key,在原始Key的前面都加上"bf:"前缀。Bitmap长度bitmapLength和哈希函数个数numHashFunctions则利用Guava版实现中的方法来计算。

然后,我们需要计算一个元素被k个哈希函数散列后,对应到Bitmap的哪些比特上。这里仍然借鉴了Guava的BloomFilterStrategies实现,采用MurmurHash和双重哈希进行散列。为了应用简单,假设所有元素固定为字符串类型,不用泛型。

然后我们就可以通过Jedis的setbit()和getbit()方法来实现向布隆过滤器中插入元素与查询元素是否存在的逻辑了。一个元素会对应多个比特,为了提高效率,流水线就派上用场了。另外,setbit指令不会重置对应Key的过期时间戳。

完毕,写个简单的单元测试吧。假设现在用布隆过滤器来存储已读帖子的ID,Key中包含用户ID和时间。每天预估的每用户最大阅读量是3000篇,最大误差3%。

观察输出。

⑨ Redis底层数据结构解密

一:摘要概述
很多 redis 的使用者都可以清晰明白的道出Redis中常用的对象如string、list、hash、set、zset,一些场景比较丰富的使用者可能会说布隆过滤器、geo、Hash等。但是对于这些对象底层实现的数据结构却是知之甚少,将会详细阐述redis中的底层数据结构。为了弥补大家的创伤,今天分享Redis底层数据结构内容。
二:SDS
string作为redis中常用对象之一,普遍用于用户信息缓存等场景。当string对象中encoding编码为embstr或raw时都是采用sds作为其底层实现
2.1 SDS结构
源码文件位于redis安装目录src下的sds.h,sds声明了五种头部类型,分别为sdshdr5、sdshdr8、sdshdr16、sdshdr32、sdshdr64。根据字符串长度创建不同头部的sds实例
struct __attribute__ ((__packed__)) sdshdr8 {
uint8_t len;
uint8_t alloc;
unsigned char flags;
char buf[];
};
属性名称作用含义
len字符串长度
alloc预分配空间大小
flags低三位用于表示sds类型,可以查看sds.h文件76-82行定义
buf[]存储字符串用数组
2.2 SDS与C字符串区别
区别描述
长度计算 c中的字符串长度计算需要数组遍历,但是redis中的sds自身维护了len属性。所以O(1)时间复杂度即可
缓冲区溢出c中字符串更改如果未提前做好内存分配则会内存溢出,但是sds则会根据alloc与len计算预留内存是否足够分配重新申请内存
动态扩展 缓冲区溢出已经阐述这个概念,sds的内存空间会在字符串内容变更时自动扩展计算。策略为当字符换小于1M时*2翻倍,大于1M时每次扩容1M
惰性释放 与空间预分配相似操作的还有内存惰性释放,即字符串删除某些内容后所占用的内存空间并不会立即释放,后续字符串变更扩展就无需再申请内存
二:ZipList
ziplist可以说把redis对于内存的极致操作体现的淋漓尽致,链表除了节点值之外还需要维护前后节点两个指针,并且还会造成内存碎片。压缩列表紧凑的内存布局,所有节点都维护在整块内存中处理
2.1 ZipList结构
属性名称作用含义
zlbytes列表健占用内存的总字节数,在对列表健内存重分配或者是计算zlend的时候使用
zltail 指向压缩列表起始地址的指针
zllen 压缩列表的节点数量
entry压缩列表保存的节点数据
zlend压缩列表的尾节点
2.2 Entry节点结构
属性名称作用含义
previous_entry_length 字节为单位记录上一个节点的长度,如果上一个字节长度小于254占用1字节。大于254占用5字节,第一个字节设置为OxFE(十进制254),后面四个字节储存长度
encoding 记录content记录的数据类型以及长度。长度一、二、五字节,值的最高位为00、01、10表示类型为字节数组,长度使用除去最高位的其它位记录。11开头表示储存整数,除去最高位其他位置表示content数据长度
content 记录压缩列表记录的数据

阅读全文

与redis数据过滤相关的资料

热点内容
韩国动漫电影推荐大全 浏览:277
思乐智空气净化器脏了怎么办 浏览:295
上千部网络好看电影一网打尽 浏览:587
那叫梅姨电器剧 浏览:325
叶枫唐三的小说 浏览:250
穿越成张大帅次子张学铭 浏览:269
硫铁矿废水处理工艺 浏览:71
都市特种兵杨洛完结版 浏览:618
穿越斗罗主角叫叶枫 浏览:819
水处理再生专用剂价格 浏览:923
贵阳万象城影院今日电影 浏览:943
国内女星露过点的电影 浏览:748
老肯空气净化器怎么换滤网 浏览:989
反渗透法的优点与缺点 浏览:27
汽车p25空气净化器怎么用 浏览:673
主角叫萧晨的穿越小说 浏览:116
爱情电影大全俄罗斯按摩店 浏览:596
复旦申花甲醛净化器怎么样 浏览:460
倪楠倪珠小雨60章原文阅读 浏览:742
邦奇cvt变速箱滤芯怎么拆 浏览:739