• [交流吐槽] MySQL 与 Redis 的区别
    MySQL 是持久化存储,存放在磁盘里面,检索的话,会涉及到一定的 IO,为了解决这个瓶颈,于是出现了缓存,比如现在用的最多的 memcached(简称mc)。首先,用户访问mc,如果未命中,就去访问 MySQL,之后像内存和硬盘一样,把数据复制到mc一部分。  Redis 和mc都是缓存,并且都是驻留在内存中运行的,这大大提升了高数据量web访问的访问速度。然而mc只是提供了简单的数据结构,比如 string存储;Redis却提供了大量的数据结构,比如string、list、set、hashset、sorted set这些,这使得用户方便了好多,毕竟封装了一层实用的功能,同时实现了同样的效果,当然用Redis而慢慢舍弃mc。  内存和硬盘的关系,硬盘放置主体数据用于持久化存储,而内存则是当前运行的那部分数据,CPU访问内存而不是磁盘,这大大提升了运行的速度,当然这是基于程序的局部化访问原理。  推理到 Redis + MySQL,它是内存+磁盘关系的一个映射,MySQL 放在磁盘,Redis放在内存,这样的话,web应用每次只访问Redis,如果没有找到的数据,才去访问 MySQL。  然而 Redis + MySQL 和内存+磁盘的用法最好是不同的。前者是内存数据库,数据保存在内存中,当然速度快。后者是关系型数据库,功能强大,数据访问也就慢。像memcache,MongoDB,Redis,都属于No SQL系列。不是一个类型的东西,应用场景也不太一样,还是要看你的需求来决定。
  • [交流吐槽] MongoDB和Redis区别
    MongoDB和Redis都是NoSQL,采用结构型数据存储。二者在使用场景中,存在一定的区别,这也主要由于二者在内存映射的处理过程,持久化的处理方法不同。MongoDB建议集群部署,更多的考虑到集群方案,Redis更偏重于进程顺序写入,虽然支持集群,也仅限于主-从模式。指标 MongoDB(v2.4.9) Redis(v2.4.17) 比较说明实现语言 C++C/C++-协议BSON、自定义二进制类Telnet-性能依赖内存,TPS较高依赖内存,TPS非常高Redis优于MongoDB可操作性丰富的数据表达、索引;最类似于关系数据库,支持丰富的查询语言数据丰富,较少的IOMongoDB优于Redis内存及存储适合大数据量存储,依赖系统虚拟内存管理,采用镜像文件存储;内存占有率比较高,官方建议独立部署在64位系统(32位有最大2.5G文件限制,64位没有改限制)Redis2.0后增加虚拟内存特性,突破物理内存限制;数据可以设置时效性,类似于memcache不同的应用角度看,各有优势可用性支持master-slave,replicaset(内部采用paxos选举算法,自动故障恢复),auto sharding机制,对客户端屏蔽了故障转移和切分机制依赖客户端来实现分布式读写;主从复制时,每次从节点重新连接主节点都要依赖整个快照,无增量复制;不支持自动sharding,需要依赖程序设定一致hash机制MongoDB优于Redis;单点问题上,MongoDB应用简单,相对用户透明,Redis比较复杂,需要客户端主动解决。(MongoDB 一般会使用replica sets和sharding功能结合,replica sets侧重高可用性及高可靠性,而sharding侧重于性能、易扩展)可靠性从1.8版本后,采用binlog方式(MySQL同样采用该方式)支持持久化,增加可靠性依赖快照进行持久化;AOF增强可靠性;增强可靠性的同时,影响访问性能MongoDB优于Redis一致性不支持事物,靠客户端自身保证支持事物,比较弱,仅能保证事物中的操作按顺序执行Redis优于MongoDB数据分析内置数据分析功能(mapreduce)不支持MongoDB优于Redis应用场景海量数据的访问效率提升较小数据量的性能及运算MongoDB优于Redis
  • [技术干货] redis 主从复制
    主从复制:主节点负责写数据,从节点负责读数据,从而实现读写分离,提高redis的高可用性。让一个服务器去复制(replicate)另一个服务器,我们称呼被复制的服务器为主节点(master),而对主服务器进行复制的服务器则被称为从节点(slave)主从复制的特点:1、一个master可以有多个slave2、一个slave只能有一个master3、数据流向是单向的,master到slave 主从复制的作用:1、数据副本:多一份或多份数据拷贝,保证redis高可用2、扩展性能:单机redis的性能是有限的,主从复制能横向扩展 如容量、QPS等主从复制实现方式客户端命令:slaveof全量复制和增量复制全量复制过程:1.  向主节点发送psync,有两个参数,第一个参数是runId,第二个参数是偏移量,第一次发送不知道主节点的runId,也不知道偏移量,因此从节点发送 ?  -12.  主节点收到消息,根据? -1 能判断出来是第一次复制,主节点把runId和offset 发送给Slave节点,3.  从节点保存主节点基本信息4-5-6.  Master节点执行bgsave生成快照,在此期间会记录后续执行的数据更改命令所更改的数据,直到主节点将生成的RDB文件传输到从节点为止,            期间Master节点执行的写操作,主节点会将缓冲区中记录的新更改的数据发送给从节点7-8      从节点清空此前的所有数据,加载RDB文件恢复数据并存入新更改的数据说明: 全量复制的性能开销:1. bgsave生成RDB文件需要的时间,2.  RDB文件在网络间的传输时间,3.  从节点的数据清空时间  ,  4.  加载RDB文件的时间  5. 可能的 AOF   重写时间 数据更改命令缓冲区repl_back_buffer用于:当Redis通过Linux中的fork()函数开辟一个子进程处理其他事务(比如主进程执行bgsave生成一个RDB文件时,或者主进程执行bgrewriteaof生成一个AOF文件时), 而主进程(即处理客户端命令的进程)后续执行的一些数据更改命令会被暂时保存在该区域,而且该区域空间有限(配置文件中repl-backlog-size 1mb即可配置该处空间大小)部分复制部分复制解决的问题:在实际环境中,主节点与从节点之间可能会发生一些网络波动等情况,导致从节点与主节点之间的网络连接断开(主从节点的Redis均未关闭),如果重新连接上后,可以使用全量复制来重新进行一次主从节点数据同步,但是全量复制会带来一个性能开销的问题,而且从节点中可能有大量数据是主节点中没有更该过的,也就是不需要进行再次同步的数据,如果使用全量复制肯定是带来了一些不必要的浪费。所以,部分复制功能就是为了解决该问题的。过程:1.  主从节点直接连接断开,2.  此时主节点继续执行的数据更改命令会被记录在一个缓冲区  repl_back_buffer  中3.  当从节点重新连接主节点时,4.   自动发出一条命令(psync offset run_id),将从节点中存储的主节点的Redis运行时id和从节点中保存的偏移量发送给主节点5.  主节点接收从节点发送的偏移量和id,对比此时主节点的偏移量和接收的偏移量,如果两个偏移量之差大于repl_back_buffer中的数据,那么就表示在断开连接期间从节点已经丢失了超出规定数量的数据,此时就需要进行全量复制了,否则就进行部分复制6.  将主节点缓冲区中的数据同步更新到从节点中,这样就实现了部分数据的复制同步,降低了性能开销主从节点的故障处理故障发生时服务自动转移(自动故障转移):即当某个节点发生故障导致停止服务时,该节点提供的服务会有另一个节点自动代替提供,这样就实现了一个高可用的效果从节点故障:即如果某个从节点发生了故障,导致无法向在该节点上的客户端提供读服务,解决办法就是使该客户端转移到另一个可用从节点上,但是在转移时,应该考虑该从节点能承受几个客户端的压力主节点故障:如果主节点发生故障,在使用主节点进行读写操作的客户端就无法使用了,而使用从节点只进行读操作的客户端还是可以继续使用的,解决办法就是从从节点中选一个节点更改为主节点,并且将原主节点的客户端连接到新的主节点上,然后通过该客户端将其他从节点连接到新的主节点中主从复制确实可以解决故障问题,但是主从复制不能实现自动故障转移,其必须要通过一些手动操作,而且非常麻烦,所以要实现自动故障转移还需要另一个功能,Redis中提供了sentinel功能来实现自动故障转移。主从节点的故障处理 1. 读写分离:即客户端发来的读写命令分开,写命令交给主节点执行,读命令交给从节点执行,不仅减少了主节点的压力,而且增强了读操作的能力;但也会造成一些问题但是主从节点之间数据复制造成的阻塞延迟也可能会导致主从不一致的情况,也就是主节点先进行了写操作,但可能因为数据复制造成的阻塞延迟,导致在从节点上进行的读操作获取的数据与主节点不一致读取过期数据:主从复制会将带有过期时间的数据一并复制到从节点中,但是从节点是没有删除数据的能力的,即使是过期数据,所以主节点中的已经删除了过期数据,但是因为主从复制的阻塞延迟问题导致从节点中的过期数据没有删除,此时客户端就会读到一个过期数据    2. 主从配置不一致:造成的问题有比如配置中的maxmemory参数如果配置不一致,比如主节点2Gb,从节点1Gb,那么就可能会导致数据丢失;以及一些其他配置问题    3. 规避全量复制:全量复制的性能开销较大,所以要尽量避免全量复制,在第一次建立主从节点关系式一定会发生全量复制;可以适当减小Redis的maxmemory参数,这样可以使得RDB更快,或者选择在客户端操作低峰期进行,比如深夜从节点中保存的主节点run_id不一致时也一定会发生全量复制(比如主节点的重启);可以通过故障转移来尽量避免,例如Redis Sentinel 与 Redis Cluster 当主从节点的偏移量之差大于命令缓冲区repl_back_buffer中对应数据的偏移差时,也会发生全量复制,也就是上面的部分复制的复制过程中所说的;可以适当增大配置文件中repl-backlog-size即数据缓冲区可尽量避免    4. 规避复制风暴:单主节点导致的复制风暴,即当主节点重启后,要向其所有的从节点都进行一次全量复制,这非常消耗性能;可以更换主从节点的拓扑结构,更换为类似树形的结构,一个主节点只与少量的从节点建立主从关系,而而这些主节点又与其他从节点构成主从关系单主节点机器复制风暴:即如果过一台机器专门用来部署多个主节点,然后其他机器部署从节点,那么一旦主节点机器宕机重启,就会引起所有的主从节点之间的全量复制,造成非常大的性能开销;可以采用多台机器,分散部署主节点,或者使用自动故障转移来将某个从节点变为主节点实现一个高可用
  • [技术干货] Redis两种持久化方式
    对Redis而言,其数据是保存在内存中的,一旦机器宕机,内存中的数据会丢失,因此需要将数据异步持久化到硬盘中保存。这样,即使机器宕机,数据能从硬盘中恢复。常见的数据持久化方式:1.快照:类似拍照记录时光,快照是某时某刻将数据库的数据做拍照记录下其数据信息。如MYSQL的Dump,Redis的RDB模式2.写日志方式:是将数据的操作全部写到日志当中,需要恢复的时候,按照日志记录的操作记录重新再执行一遍。例如MYSQL的Binlog,Redis的AAOF模式、RDB说明:redis默认开启,将redis在内存中保存的数据,以快照的方式持久化到硬盘中保存。触发机制:1.save命令:阻塞方式,需要等redis执行完save后,才能执行其他get、set等操作。同步方式2.bgsave命令:非阻塞,其原理是调用linux 的  fork()函数,创建redis的子进程,子进程进行创建  rdb 文件的操作。异步方式,3.自动方式:在redis.conf文件中配置,如下  save  <指定时间间隔>  <执行指定次数更新操作>  ,save  60  10000 表示 60秒年内有10000次操作会自动生成rdb文件。4.其他方式4.1  执行flushall命令,清空数据,几乎不用4.2  执行shutdown命令,安全关闭redis不丢失数据,几乎用不到。4.3  主从复制,在主从复制的时候,rdb文件作为媒介来关联主节点和从节点的数据一致。RDB优缺点优点:1 适合大规模的数据恢复。2 如果业务对数据完整性和一致性要求不高,RDB是很好的选择。缺点:1 不可控,容易丢失数据:数据的完整性和一致性不高,因为RDB可能在最后一次备份时宕机了。2 耗时耗性能:备份时占用内存,因为Redis 在备份时会独立创建一个子进程,将数据写入到一个临时文件(此时内存中的数据是原来的两倍哦),最后再将临时文件替换之前的备份文件。所以Redis 的持久化和数据的恢复要选择在夜深人静的时候执行是比较合理的。AOF说明: redis默认不开启,采用日志的形式来记录每个写操作,并追加到 .aof 文件中。Redis 重启的会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作生成AOF的三种策略:1. always : 每条命令都会刷新到缓冲区,把缓冲区fsync到硬盘,对硬盘IO压力大,一般sata盘只有几百TPS,如果redis的写入量非常大,那对硬盘的压力也横刀。2. everysec:  每秒把缓冲区fsync 到硬盘,如果出现故障,会丢失1s(默认配置是1秒)的数据。一般使用这种。3. no : 由操作系统来定什么时候fsync到硬盘中。 缺点:不可控 AOF重写:把过期的,没有用的,重复的,可优化的命令简化为很小的aof文件。实际上是redis内存中的数据回溯成aof文件。如下图所示:作用:1.减少硬盘占用量2.加快恢复速度 AOF重写的实现方式1.bgrewriteaof   命令 : 从redis的主进程fork一个子进程生成包含当前redis内存数据的最小命令集、2.AOF重写配置:# 1. aof文件增长率 auto-aof-rewrite-percentage 100# 2. aof文件重写需要的尺寸 auto-aof-rewrite-min-size 64mb自动触发时机:(需要同时满足)当前的aof文件大小   >   aof文件重写需要的尺寸        (aof当前文件大小 -  上次aof的文件大小)/  上次aof文件大小  >  aof文件增长率 AOF优缺点优点:1.数据的完整性和一致性更高缺点:1.因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢。2. AOF每秒fsync一次指令硬盘,如果硬盘IO慢,会阻塞父进程;风险是会丢失1秒多的数据;在Rewrite过程中,主进程把指令存到mem-buffer中,最后写盘时会阻塞主进程。关于Redis持久化方式RDB和AOF的缺点原因是redis持久化方式的痛点,缺点比较明显。1、RDB需要定时持久化,风险是可能会丢两次持久之间的数据,量可能很大。2、AOF每秒fsync一次指令硬盘,如果硬盘IO慢,会阻塞父进程;风险是会丢失1秒多的数据;在Rewrite过程中,主进程把指令存到mem-buffer中,最后写盘时会阻塞主进程。3、这两个缺点是个很大的痛点。为了解决这些痛点,GitHub的两位工程师 Bryana Knight 和 Miguel Fernández 日前写了一篇 文章 ,讲述了将持久数据从Redis迁出的经验: http://www.open-open.com/lib/view/open1487736984424.html如何选择RDB和AOF建议全都要。1、对于我们应该选择RDB还是AOF,官方的建议是两个同时使用。这样可以提供更可靠的持久化方案。在redis 4.0 之后,官方提供了混合持久化模式,具体如下持久化文件结构上半段RDB格式,后半段是AOF模式。
  • [技术干货] GaussDB(for Redis)新特性发布:增强版前缀扫描与多租隔离[转载]
    近期,华为云GaussDB(for Redis)缓存数据库再次推出全新版本,携新特性重磅来袭!GaussDB(for Redis)是华为云推出的企业级分布式KV数据库,它完全兼容Redis协议,提供丰富的数据类型,基于云原生存储计算分离架构,在成本、可靠性等方面为企业带来全新价值。 本次GaussDB(for Redis)推出的全新特性,不仅对基础性能和连接管理等进行了大幅优化,同时突破开源Redis短板,实现增强版前缀搜索和集群版多租隔离功能,前缀搜索时延较开源Redis降低千倍,为助力企业业务发展带来了更多可能。关键特性1:增强版前缀扫描,千倍性能提升GaussDB(for Redis)推出的增强版前缀扫描功能,优化了String、Hash、Set、Zset四种数据类型scan的前缀搜索。GaussDB(for Redis)的SCAN、HSCAN、SSCAN、ZSCAN命令在使用方法上与开源Redis完全兼容,但前缀匹配模式的性能更为优秀,从开源的耗时O(N)优化到O(logN + M)(其中N是整体数据量,M是匹配的数据量)。下面根据某客户实际场景,对比GaussDB(for Redis)和开源Redis的性能:数据:500w个key,均为String,范围为“1”~“5000000”, value大小为100B。命令:Scan 0 Match 499999* Count 100。在500w个key中搜索11个key。结果:开源Redis为7.67s ,GaussDB(for Redis)仅为2.92ms,快了2600倍,且开源Redis在返回搜索结果前返回了4.98w+次的空结果,而GaussDB(for Redis)第一次就返回了搜索结果。开源Redis:GaussDB(for Redis):在互联网业务中,诸如批量查找/删除一批相同前缀的key是很常见的业务场景,在上百万的数据量下,开源Redis的秒级时延显然是不可接受的。GaussDB(for Redis)针对这一场景进行了有效优化,将时延降低上千倍至毫秒级,带来了极致的性能体验。关键特性2:多租隔离,集群版业务数据隔离能力GaussDB(for Redis) 提供的多租隔离功能,允许用户为不同的业务创建不同的DB,实现不同业务数据隔离。使用方法上,GaussDB(for Redis)的多租隔离功能与开源Redis单机版本的多DB用法保持完全兼容(开源Redis集群版本不支持多DB)。用户可以通过SELECT DB来切换/新建不同的DB给不同的业务使用,通过FLUSHDB删除一个DB中的全部数据而不影响其他DB,从而高效地实现多租隔离效果。GaussDB(for Redis)多DB实现业务多租隔离GaussDB(for Redis)的多DB核心价值在于:集群版多DB:GaussDB(for Redis)集群版本可支持多DB;开源Redis的“多DB”只能用于单机,不支持集群。大规模多DB:GaussDB(for Redis)单实例支持65536个DB,搞定多业务多租隔离。高扩展性:开源Redis单机扩容到64G已经是极限,更不用说fork导致的容量利用率只有50%。GaussDB(for Redis)吞吐可水平扩展至百万QPS,容量支持12TB,解决了扩展性问题。低成本:GaussDB(for Redis)相比开源Redis,成本可降20%~70%。多租隔离是数据库的必备功能,在实际业务场景中,不同模块共享同一Redis实例是很常见的需求。GaussDB(for Redis)超越开源Redis,支持集群版本下的多DB,依托现有的秒级弹性扩缩容能力,在海量业务压力下仍能为客户提供灵活便捷的业务数据访问控制服务。目前,GaussDB(for Redis)已经凭借出色的产品实力在游戏系统、电商平台、推荐系统、社交媒体、物联网等众多企业级应用场景中发挥出巨大作用,而新推出的增强版前缀扫描与多租隔离两大功能特性,将以更优异的能力使企业在降本的同时实现增效,助力企业高效数字化!连接:https://bbs.huaweicloud.com/blogs/352808
  • [技术干货] GaussDB(for Redis)新特性发布:增强版前缀扫描与多租隔离[转载]
    近期,华为云GaussDB(for Redis)缓存数据库再次推出全新版本,携新特性重磅来袭!GaussDB(for Redis)是华为云推出的企业级分布式KV数据库,它完全兼容Redis协议,提供丰富的数据类型,基于云原生存储计算分离架构,在成本、可靠性等方面为企业带来全新价值。 本次GaussDB(for Redis)推出的全新特性,不仅对基础性能和连接管理等进行了大幅优化,同时突破开源Redis短板,实现增强版前缀搜索和集群版多租隔离功能,前缀搜索时延较开源Redis降低千倍,为助力企业业务发展带来了更多可能。关键特性1:增强版前缀扫描,千倍性能提升GaussDB(for Redis)推出的增强版前缀扫描功能,优化了String、Hash、Set、Zset四种数据类型scan的前缀搜索。GaussDB(for Redis)的SCAN、HSCAN、SSCAN、ZSCAN命令在使用方法上与开源Redis完全兼容,但前缀匹配模式的性能更为优秀,从开源的耗时O(N)优化到O(logN + M)(其中N是整体数据量,M是匹配的数据量)。下面根据某客户实际场景,对比GaussDB(for Redis)和开源Redis的性能:数据:500w个key,均为String,范围为“1”~“5000000”, value大小为100B。命令:Scan 0 Match 499999* Count 100。在500w个key中搜索11个key。结果:开源Redis为7.67s ,GaussDB(for Redis)仅为2.92ms,快了2600倍,且开源Redis在返回搜索结果前返回了4.98w+次的空结果,而GaussDB(for Redis)第一次就返回了搜索结果。开源Redis:GaussDB(for Redis):在互联网业务中,诸如批量查找/删除一批相同前缀的key是很常见的业务场景,在上百万的数据量下,开源Redis的秒级时延显然是不可接受的。GaussDB(for Redis)针对这一场景进行了有效优化,将时延降低上千倍至毫秒级,带来了极致的性能体验。关键特性2:多租隔离,集群版业务数据隔离能力GaussDB(for Redis) 提供的多租隔离功能,允许用户为不同的业务创建不同的DB,实现不同业务数据隔离。使用方法上,GaussDB(for Redis)的多租隔离功能与开源Redis单机版本的多DB用法保持完全兼容(开源Redis集群版本不支持多DB)。用户可以通过SELECT DB来切换/新建不同的DB给不同的业务使用,通过FLUSHDB删除一个DB中的全部数据而不影响其他DB,从而高效地实现多租隔离效果。GaussDB(for Redis)多DB实现业务多租隔离GaussDB(for Redis)的多DB核心价值在于:集群版多DB:GaussDB(for Redis)集群版本可支持多DB;开源Redis的“多DB”只能用于单机,不支持集群。大规模多DB:GaussDB(for Redis)单实例支持65536个DB,搞定多业务多租隔离。高扩展性:开源Redis单机扩容到64G已经是极限,更不用说fork导致的容量利用率只有50%。GaussDB(for Redis)吞吐可水平扩展至百万QPS,容量支持12TB,解决了扩展性问题。低成本:GaussDB(for Redis)相比开源Redis,成本可降20%~70%。多租隔离是数据库的必备功能,在实际业务场景中,不同模块共享同一Redis实例是很常见的需求。GaussDB(for Redis)超越开源Redis,支持集群版本下的多DB,依托现有的秒级弹性扩缩容能力,在海量业务压力下仍能为客户提供灵活便捷的业务数据访问控制服务。目前,GaussDB(for Redis)已经凭借出色的产品实力在游戏系统、电商平台、推荐系统、社交媒体、物联网等众多企业级应用场景中发挥出巨大作用,而新推出的增强版前缀扫描与多租隔离两大功能特性,将以更优异的能力使企业在降本的同时实现增效,助力企业高效数字化!连接:https://bbs.huaweicloud.com/blogs/352808
  • [问题求助] GaussDB(for Redis) 是闭源的吗 ?
    个人无法免费试用,使用?
  • [技术干货] gaussdb for redis 体验[转载]
    创建1、首先 是找到使用页面 https://activity.huaweicloud.com/free_test/index.html2、全新注册用户,自行解决。(ps:需要邮箱认证,我的邮箱之前 注册过无法重复注册,原账号找回密码需要很多注册信息。。。,最后用guge的邮箱。。)3、点击0元试用 自动跳转到实例控制台,这里体验很流畅。4、点击实例列表名称进入 实例详情,一个月31天。这里开个玩笑,我买12个月 算31x12 不。。。好了进入主页面,咱们开始 详细的了解 华为云的redis实例详情如何了。二  详情页面详解1、基本信息采用arm架构,维护时间窗口默认帮用户设置了。这也是行业惯例。2、拓扑信息基本的主从架构,实例id 也是默认映射主节点的地址,一会可以连接实例看下支持的命令 和主从连接信息。3、连接信息连接信息访问方式免密访问连接地址redis-87f5d492-8b12-4d6f-9d6e-2984bec7e1af.cn-east-3.dcs.myhuaweicloud.com:6379只读地址redis-87f5d492-8b12-4d6f-9d6e-2984bec7e1af-readonly.cn-east-3.dcs.myhuaweicloud.com:6379IP地址172.31.201.38:6379公网访问查看文档我通过电脑自带的redis-cli 无法连接地址【 redis-87f5d492-8b12-4d6f-9d6e-2984bec7e1af.cn-east-3.dcs.myhuaweicloud.com 】,我以为是白名单的问题。然后在实例配置白名单配置里,设置自己的公网地址。(浏览器输入ip.cn,找到自己的公网地址),然后添加我的公网ip地址后 依然不可以访问。仔细 一看如下文字所示,也就是 说这里的配置只是vpc内部的连接白名单。所以,url连接不是用来公网访问的,而是用来内部dns定向访问的。比如不同的子网划分,不同的地址映射吧,这样可以无需修改应用的ip地址配置。您还没有添加任何白名单,所有与VPC互通的IP地址均可访问实例。若需要指定的IP地址才能访问,请将这些IP地址加入白名单。那么如何公网访问呢?连接如下,需要自己开一个云主机用nginx的tcp代理来 映射,6379端口,操作指南详见连接    使用Nginx实现公网访问Redis 4.0/5.0的单机/主备/Proxy集群实例_分布式缓存服务 DCS_最佳实践_华为云 (huaweicloud.com)然后返回体验页面 https://activity.huaweicloud.com/free_test/index.html。 这里开始白嫖一个云主机,发现云主机被体验光了。好吧,下一篇博客在细说 通过云主机的redis-cli连接。这里先小结下体验感受:由于我使用过谷歌 和 redislab的kv服务,国内阿里云的kv服务,体验这里给在国内比较给中上评价吧,如果在国际上就比较差了,连接地址和 只读地址 都是无法通过公网连接的。原因如下:redislabs的使用企业版 url连接自动连上,他是自动化的dbaas服务部署是通过调用aws的接口 创建小实例,并且是可以直接公网访问的。阿里的实例是可以自动开公网访问,并且做到了一个url地址既可以公网也可以内网,并且就在实例的详情主页里实例【公网访问】开通一点击就OK,设置完白名单可以很方便通过url了解访问。4、web console体验直接在概览页面右上角点击 【连接Redis】,跳转到 web的console页面。页面很简洁。页面有db信息,并且自动auth成功,推出当前实例定跳转到 实例列表页面。进行简单操作 set hw hwc,info all。回显如下信息set hw hwcOKinfo all# Server redis_version:5.0.14 patch_version:5.0.14.1 redis_git_sha1:00000000 redis_git_dirty:0 redis_build_id:0 redis_mode:standalone os:Linux arch_bits:64 multiplexing_api:epoll atomicvar_api:atomic-builtin gcc_version:0.0.0 process_id:1 run_id:a7b30d214bf934f5a3254a6596f0bd83dd5c850d tcp_port:2407 uptime_in_seconds:2539 uptime_in_days:0 hz:10 configured_hz:10 lru_clock:8266221 executable:redis-server config_file:redis.conf instance_id:87f5d492-8b12-4d6f-9d6e-2984bec7e1af # Clients connected_clients:7 client_recent_max_input_buffer:2 client_recent_max_output_buffer:0 blocked_clients:0 rx_controlled_clients:0 total_real_rx_controlled:0 total_tx_controlled:0 total_rx_controlled:0 proxy_header_error:0 # Memory used_memory:2341624 used_memory_human:2.23M used_memory_rss:9961472 used_memory_rss_human:9.50M used_memory_peak:2464272 used_memory_peak_human:2.35M used_memory_peak_perc:95.02% used_memory_overhead:2300662 used_memory_startup:1082800 used_memory_dataset:40962 used_memory_dataset_perc:3.25% allocator_allocated:2725304 allocator_active:3088384 allocator_resident:19886080 total_system_memory:1081361883136 total_system_memory_human:1007.10G used_memory_lua:37888 used_memory_lua_human:37.00K used_memory_scripts:0 used_memory_scripts_human:0B number_of_cached_scripts:0 maxmemory:268435456 maxmemory_human:256.00M maxmemory_policy:volatile-lru allocator_frag_ratio:1.13 allocator_frag_bytes:363080 allocator_rss_ratio:6.44 allocator_rss_bytes:16797696 rss_overhead_ratio:0.50 rss_overhead_bytes:-9924608 mem_fragmentation_ratio:4.29 mem_fragmentation_bytes:7641792 mem_not_counted_for_evict:106 mem_replication_backlog:1048576 mem_clients_slaves:17042 mem_clients_normal:152066 mem_aof_buffer:106 mem_allocator:jemalloc-5.1.0 active_defrag_running:0 lazyfree_pending_objects:0 # Persistence loading:0 rdb_changes_since_last_save:1 rdb_bgsave_in_progress:0 rdb_last_save_time:1652430851 rdb_last_bgsave_status:ok rdb_last_bgsave_time_sec:0 rdb_current_bgsave_time_sec:-1 rdb_last_cow_size:299008 aof_enabled:1 aof_rewrite_in_progress:0 aof_rewrite_scheduled:0 aof_last_rewrite_time_sec:-1 aof_current_rewrite_time_sec:-1 aof_last_bgrewrite_status:ok aof_last_write_status:ok aof_last_cow_size:0 aof_current_size:53 max_aof_size:1342177280 aof_base_size:0 aof_pending_rewrite:0 aof_buffer_length:0 aof_rewrite_buffer_length:0 aof_pending_bio_fsync:0 total_aof_write_error:0 aof_delayed_fsync:0 # Stats total_connections_received:717 total_commands_processed:15038 instantaneous_ops_per_sec:5 total_net_input_bytes:889498 total_net_output_bytes:8147140 instantaneous_input_kbps:0.41 instantaneous_output_kbps:1.32 rejected_connections:0 sync_full:1 sync_partial_ok:0 sync_partial_err:0 expired_keys:0 expired_stale_perc:0.00 expired_time_cap_reached_count:0 evicted_keys:0 keyspace_hits:0 keyspace_misses:0 pubsub_channels:1 pubsub_patterns:0 latest_fork_usec:432 migrate_cached_sockets:0 slave_expires_tracked_keys:0 active_defrag_hits:0 active_defrag_misses:0 active_defrag_key_hits:0 active_defrag_key_misses:0 # Replication role:master connected_slaves:1 slave0:ip=192.168.30.31,port=3184,state=online,offset=663452,lag=0 master_replid:c07fd7bb03ad6d1628cde2f017a34d22ea8b36d0 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:663629 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:663629 # CPU used_cpu_sys:1.036002 used_cpu_user:2.197352 used_cpu_sys_children:0.000000 used_cpu_user_children:0.002273 # Commandstats cmdstat_dcs.getBandwidth:calls=2,usec=16,usec_per_call=8.00 cmdstat_publish:calls=3722,usec=21106,usec_per_call=5.67 cmdstat_ping:calls=7298,usec=9439,usec_per_call=1.29 cmdstat_replconf:calls=2536,usec=4751,usec_per_call=1.87 cmdstat_set:calls=1,usec=10,usec_per_call=10.00 cmdstat_command:calls=4,usec=2607,usec_per_call=651.75 cmdstat_client:calls=6,usec=10,usec_per_call=1.67 cmdstat_subscribe:calls=3,usec=11,usec_per_call=3.67 cmdstat_info:calls=1399,usec=109527,usec_per_call=78.29 cmdstat_config:calls=23,usec=428,usec_per_call=18.61 cmdstat_slowlog:calls=43,usec=227,usec_per_call=5.28 cmdstat_psync:calls=1,usec=595,usec_per_call=595.00 # Cluster cluster_enabled:0 # Keyspace db0:keys=1,expires=0,avg_ttl=0在输入 config get * 看看配置信息config get *dbfilename redis.rdb requirepass masterauth cluster-announce-ip unixsocket /opt/redis/redis.sock logfile /var/log/redis.log pidfile /opt/redis/redis.pid slave-announce-ip replica-announce-ip maxmemory 268435456 max-aof-memory-multiplier 5 max-aof-size 1342177280 proto-max-bulk-len 536870912 client-query-buffer-limit 1073741824 maxmemory-samples 5 lfu-log-factor 10 lfu-decay-time 1 timeout 0 active-defrag-threshold-lower 10 active-defrag-threshold-upper 100 active-defrag-ignore-bytes 104857600 active-defrag-cycle-min 5 active-defrag-cycle-max 75 active-defrag-max-scan-fields 1000 auto-aof-rewrite-percentage 0 auto-aof-rewrite-min-size 67108864 hash-max-ziplist-entries 512 hash-max-ziplist-value 64 stream-node-max-bytes 4096 stream-node-max-entries 100 list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 lua-time-limit 5000 slowlog-log-slower-than 10000 latency-monitor-threshold 0 slowlog-max-len 128 port 2407 cluster-announce-port 0 cluster-announce-bus-port 0 tcp-backlog 10000 databases 256 repl-ping-slave-period 10 repl-ping-replica-period 10 repl-timeout 60 repl-backlog-size 1048576 repl-backlog-ttl 3600 maxclients 10010 watchdog-period 0 slave-priority 100 replica-priority 100 slave-announce-port 0 replica-announce-port 0 min-slaves-to-write 0 min-replicas-to-write 0 min-slaves-max-lag 10 min-replicas-max-lag 10 hz 10 cluster-node-timeout 15000 cluster-migration-barrier 1 cluster-slave-validity-factor 10 cluster-replica-validity-factor 10 repl-diskless-sync-delay 5 tcp-keepalive 30 incremental-eviction-num 65535 active-expire-num 20 active-expire-cycle-slow-time-perc 25 cluster-require-full-coverage yes cluster-slave-no-failover no cluster-replica-no-failover no no-appendfsync-on-rewrite yes slave-serve-stale-data yes replica-serve-stale-data yes slave-read-only yes replica-read-only yes slave-ignore-maxmemory yes replica-ignore-maxmemory yes stop-writes-on-bgsave-error yes daemonize no rdbcompression no rdbchecksum yes activerehashing yes activedefrag no protected-mode no repl-disable-tcp-nodelay no repl-diskless-sync no aof-rewrite-incremental-fsync yes rdb-save-incremental-fsync yes aof-load-truncated yes aof-use-rdb-preamble yes lazyfree-lazy-eviction yes lazyfree-lazy-expire yes lazyfree-lazy-server-del yes slave-lazy-flush yes replica-lazy-flush yes dynamic-hz yes master-read-only no vpc-endpoint-proxy-header no tenant-sync no enable-write-protection no maxmemory-policy volatile-lru loglevel notice supervised no appendfsync no syslog-facility local0 appendonly yes dir /opt/redis save client-output-buffer-limit normal 0 0 0 slave 26843545 26843545 60 pubsub 33554432 8388608 60 unixsocketperm 600 slaveof notify-keyspace-events xE bind 192.168.36.137使用小结:由于带了控制台功能,那么开云主机的需要就不那么紧要了,客户几乎可以执行所有的可配置的 命令。命令支持的也很全面原文连接:https://bbs.huaweicloud.com/blogs/352815
  • [技术干货] 暴露数据库数量创新高,中美占比最多,Redis 排第一
    BleepingComputer 网站消息,威胁情报和研究公司 Group-IB 共享的一份报告中显示,公开暴露在互联网上的数据库数量近期有所增加 ,从 2021 年的 308000 个持续增长,截至 2022 年第一季度,暴露的数据库峰值数量已达 91200 个,创造了历史记录。在大多数情况下,数据库被公开至网络是由于配置错误的原因造成,黑客常常使用可从开放网络访问的搜索引擎索引系统来寻找这些数据库,以窃取内容或进行金融勒索。Group-IB 使用其攻击面管理解决方案扫描整个 IPv4 空间来查找与访问数据库相关的开放端口,并检查索引或表是否可用。Group-IB 的攻击面管理产品负责人 Tim Bobak 告诉 BleepingComputer,该公司的解决方案仅限于检查数据库是否暴露,不会收集或分析数据库内容。以这种方式收集的遥测数据不会显示开放数据库是否容易受到安全漏洞的影响,或者未经授权的一方是否在暴露在网络上时访问了它们。中美数据库占比最多Group-IB 发现,大多数暴露的数据库都位于美国和中国服务器,德国、法国和印度也占很多。在暴露实例中使用的数据库管理系统中,今年一季度的暴露数量最多的是 Redis,是排名第二的 MongoDB 的近两倍, MySQL 则占比较少。目前这些管理系统已采取措施,在管理员将实例配置为无需密码即可公开访问时会对管理员进行提醒,但目前问题仍然存在。专攻数据库安全的安全研究员 Bob Diachenko 告诉 Bleeping Computer:目前一些数据库供应商引入的 dbms (数据库管理系统)越复杂,反而越容易出现配置错误,从而在无意中暴露数据。他认为,数据库的目的不仅是存储数据,而且还允许以即时和便捷的方式共享这些数据,并由其他团队成员对其进行分析,如今,越来越多的人参与到数据库管理过程中,为了试图简化和加快访问速度,甚至对登录措施进行了省略。同时,管理员平均需要 170 天的时间来发现错误配置并修复暴露问题,这足以让恶意行为者找到实例并窃取其内容。预防措施Group-IB 的 Bobak 指出,大多数困扰数据库安全的问题都可以轻松预防。如果管理员在设置和维护数据库时遵循特定关键措施,则可以确保数据库安全。总结为以下几点:如无必要,确保数据库不公开;使数据库管理系统保持最新版本,以减少可利用的缺陷;使用强用户身份验证;为所有存储的信息部署强大的数据加密协议;使用采用数据包过滤器、数据包检查和代理的数据库和 Web 应用程序防火墙;使用实时数据库监控;避免使用将数据库暴露给恶意扫描的默认网络端口;尽可能遵循服务器分段做法;以加密形式对数据进行离线备份。
  • [交流分享] 关于幂等性的学习笔记
    最基础的概念,什么是幂等性?幂等性:提交多次的情况下,结果都一样。比如数据库查询,可称为天然幂等性,即查询多次结果都一样,无需人为去做幂等性操作。但是update table set value=value+1 where id=1,每次执行的结构都会发生变化,不是幂等。inter into table(id,name)values(1,‘name’),如id不是主键或者没有唯一索引,重复操作上面的业务,会插入多条数据,不具备幂等性;所以我们在什么情景下需要确保幂等性呢?用户多次点击保存按钮用户保存成功后,返回上一页再次保存微服务相互调用,由于网络原因,导致请求失败解决方案一、token机制:1、根据业务场景,判断哪些业务存在幂等性问题,在执行业务之前先获取token,将token缓存止redis中2、调用业务接口时,将token携带过去,一般放在请求头,作为Auth认证3、服务器判断token是否存在于redis中,存在表示第一次请求,然后删除token,继续执行业务4、如果不存在,则表示反复操作,不执行业务逻辑,直接返回重复标志!结束风险性:业务执行前删除还是后删除token?如果是执行后删除,在业务执行中,未删除token,用户又点了请求进来,那么则无法保障幂等性。如果是执行前删除,在分布式下,用户快速请求2次,这时2个请求同时到redis去获取token,对比成功,同时删除,同时执行业务,那么也无法保障幂等性。so:使用执行前删除,在分布式情况下,获取,对比,删除必须确保原子性,所以要加分布式锁。二、加锁1、数据库锁select * from table where … for update2、业务层面加分布式锁将获取、对比、删除作为一个原子性的操作加锁,处理完成后释放锁,确保串行操作。三、约束数据库唯一约束:通过主键、唯一索引,确保无法重复新增同一笔数据,这就能确保幂等性
  • [新手课堂] 鲲鹏redis 优化系列(六)高可用集群 Redis Cluster 的认识
    ## 一、redis哨兵+主从的问题 假设我们在一台主从机器上配置了200G内存,但是业务需求是需要500G的时候,主从结构+哨兵可以实现高可用故障切换+冗余备份,但是并不能解决数据容量的问题,用哨兵,redis每个实例也是全量存储,每个redis存储的内容都是完整的数据,浪费内存且有木桶效应。 为了最大化利用内存,可以采用cluster集群,就是分布式存储。即每台redis存储不同的内容。 Redis 分布式方案一般有两种: ①、客户端分区方案:优点是分区逻辑可控,缺点是需要自己处理数据路由、高可用、故障转移等问题,比如在redis2.8之前通常的做法是获取某个key的hashcode,然后取余分布到不同节点,不过这种做法无法很好的支持动态伸缩性需求,一旦节点的增或者删操作,都会导致key无法在redis中命中。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/27/1651072676474437258.png) ②、代理方案:优点是简化客户端分布式逻辑和升级维护便利,缺点是加重架构部署复杂度和性能损耗,比如twemproxy、Codis ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/27/1651072688146372437.png) ③、Redis官方为我们提供了专有的集群方案:Redis Cluster,它非常优雅地解决了 Redis 集群方面的问题,部署方便简单,因此理解应用好 Redis Cluster 将极大地解放我们使用分布式 Redis 的工作量。 ## 二、Redis Cluster ### 1、简介 Redis Cluster 是 Redis 的分布式解决方案,在3.0版本正式推出,有效地解决了 Redis 分布式方面的需求。当遇到单机内存、并发、流量等瓶颈时,可以采用 Cluster 架构方案达到负载均衡的目的。 架构图: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/27/1651072702175703598.png) 在上面这个图中,每一个蓝色的圈都代表着一个redis的服务器节点。它们任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点,对其进行存取和其他操作。 Redis 集群提供了以下两个好处: ①、将数据自动切分到多个节点的能力。 ②、当集群中的一部分节点失效或者无法进行通讯时, 仍然可以继续处理命令请求的能力,拥有自动故障转移的能力。 ### 2、redis cluster VS replication + sentinel如何选择? 如果你的数据量很少,主要是承载高并发高性能的场景,比如你的缓存一般就几个G,单机足够了。 Replication:一个mater,多个slave,要几个slave跟你的要求的读吞吐量有关系,结合sentinel集群,去保证redis主从架构的高可用性,就可以了。 redis cluster:主要是针对海量数据+高并发+高可用的场景,海量数据,如果你的数据量很大,那么建议就用redis cluster。 ### 3、Redis Cluster集群中的数据分布是如何进行的? 什么是数据分布?数据分布有两种方式,顺序分区和哈希分区。 分布式数据库首先要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整体数据的一个子集。 顺序分布就是把一整块数据分散到很多机器中,如下图所示。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/27/1651072720825984183.png) 顺序分布一般都是平均分配的。 哈希分区: 如下图所示,1~100这整块数字,通过 hash 的函数,取余产生的数。这样可以保证这串数字充分的打散,也保证了均匀的分配到各台机器上。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/27/1651072732421268608.png) 哈希分布和顺序分布只是场景上的适用。哈希分布不能顺序访问,比如你想访问1~100,哈希分布只能遍历全部数据,同时哈希分布因为做了 hash 后导致与业务数据无关了。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/27/1651072744339188917.png) ### 4、数据倾斜与数据迁移跟节点伸缩 顺序分布是会导致数据倾斜的,主要是访问的倾斜。每次点击会重点访问某台机器,这就导致最后数据都到这台机器上了,这就是顺序分布最大的缺点。 但哈希分布其实是有个问题的,当我们要扩容机器的时候,专业上称之为“节点伸缩”,这个时候,因为是哈希算法,会导致数据迁移。 ### 5、哈希分区方式 因为redis-cluster使用的就是哈希分区规则所以分析下几种分区形式 **5.1、节点取余分区** 使用特定的数据(包括redis的键或用户ID),再根据节点数量N,使用公式:hash(key)%N计算出一个0~(N-1)值,用来决定数据映射到哪一个节点上。即哈希值对节点总数取余。 缺点:当节点数量N变化时(扩容或者收缩),数据和节点之间的映射关系需要重新计算,这样的话,按照新的规则映射,要么之前存储的数据找不到,要么之前数据被重新映射到新的节点(导致以前存储的数据发生数据迁移) 实践:常用于数据库的分库分表规则,一般采用预分区的方式,提前根据数据量规划好分区数,比如划分为512或1024张表,保证可支撑未来一段时间的数据量,再根据负载情况将表迁移到其他数据库中。 **5.2、一致性哈希** 一致性哈希分区(Distributed Hash Table)实现思路是为系统中每个节点分配一个 token,范围一般在0~232,这些 token 构成一个哈希环。数据读写执行节点查找操作时,先根据 key 计算 hash 值,然后顺时针找到第一个大于等于该哈希值的 token 节点 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/27/1651072757789793590.png) 上图就是一个一致性哈希的原理解析。 假设我们有 n1~n4 这四台机器,我们对每一台机器分配一个唯一 token,每次有数据(图中黄色代表数据),一致性哈希算法规定每次都顺时针漂移数据,也就是图中黄色的数 据都指向 n3。 这个时候我们需要增加一个节点 n5,在 n2 和 n3 之间,数据还是会发生漂移(会偏移到大于等于的节点),但是这个时候你是否注意到,其实只有 n2~n3 这部分的数据被漂移,其他的数据都是不会变的,这种方式相比节点取余最大的好处在于加入和删除节点只影响哈希环中相邻的节点,对其他节点无影响 缺点:每个节点的负载不相同,因为每个节点的hash是根据key计算出来的,换句话说就是假设key足够多,被hash算法打散得非常均匀,但是节点过少,导致每个节点处理的key个数不太一样,甚至相差很大,这就会导致某些节点压力很大 实践:加减节点会造成哈希环中部分数据无法命中,需要手动处理或者忽略这部分数据,因此一致性哈希常用于缓存场景。 **5.3、虚拟槽分区\*(目前在redis集群中 数据存储和读取常用的方式就是这种 槽 的方式)\** 虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有数据映射到一个固定范围的整数集合中,整数定义为槽(slot)。这个范围一般远远大于节点数,比如 Redis Cluster 槽范围是0~16383(也就是16384个槽。redis集群规定了16384个槽,这些槽将会平均分配给不同的redis节点)。槽是集群内数据管理和迁移的基本单位(也就是说 数据是存储在槽中,而槽被分配在了不同的redis节点中)。采用大范围槽的主要目的是为了方便数据拆分和集群扩展。每个节点会负责一定数量的槽,具体看下图所示。 当前集群有5个节点,每个节点平均大约负责3276个槽。由于采用高质量的哈希算法,每个槽所映射的数据通常比较均匀,将数据平均划分到5个节点进行数据分区。Redis Cluster 就是采用虚拟槽分区,下面就介绍 Redis 数据分区方法。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/27/1651072773151221557.png) **上图步骤大概执行如下(数据写入):** ①、redis根据所给定的key进行CRC16算法之后 算出一个结果,然后 再对该结果 进行16384取模(即 对该结果进行16384求余数),得到一个槽。 这样每个key都会对应一个编号在0---16383之间的槽号码,redis会根据节点数量大致均等的原则将哈希槽映射到不同的节点上。比如有3个redis节点,把16384分成3段,每个节点承担一段范围的哈希槽。 **注意:**这里是对16384进行取模,上图中那个CRC16(key)&16383写错了 正确公式为:CRC16(key)%16384 ②、再根据所得的槽位数,获得这个槽所在的redis节点(假设是Z节点)。 ③、连接Z节点,将该key保存到Z这台redis节点上。 **数据读取也是同理,都是根据key得到槽,根据槽得到该槽所在的redis节点,然后连接该redis节点进行数据读取操作。** 每当 key 访问过来,Redis Cluster 会计算哈希值是否在这个区间里。它们彼此都知道对应的槽在哪台机器上,这样就能做到平均分配了。 **redis-cluster集群方面有一些限制:** Redis集群相对单机来说,在功能上存在一些限制,需提前了解,在使用时做好规避。限制如下: key批量操作支持有限。如mset、mget等。 ## 总结redis主从、哨兵、集群的概念: 【redis主从】: 是备份关系, 我们操作主库,数据也会同步到从库。 如果主库机器坏了,从库可以上。就好比你 D盘的片丢了,但是你移动硬盘里边备份有。 【redis哨兵】: 哨兵保证的是HA(高可用),保证特殊情况故障自动切换,哨兵盯着你的“redis主从集群”,如果主库死了,它会告诉你新的老大是谁。 哨兵:主要针对redis主从中的某一个单节点故障后,无法自动恢复的解决方案。(哨兵 保证redis主从的高可用) 【redis集群】: 集群保证的是高并发,因为多了一些兄弟帮忙一起扛。同时集群会导致数据的分散,整个redis集群会分成一堆数据槽,即不同的key会放到不不同的槽中。 集群主要针对单节点容量、高并发问题、线性可扩展性的解决方案。 集群:是为了解决redis主从复制中 单机内存上限和并发问题,假如你现在的服务器内存为256GB,当达到这个内存时redis就没办法再提供服务,同时数据量能达到这个地步写数据量也会很大,容易造成缓冲区溢出,造成从节点无限的进行全量复制导致主从无法正常工作。
  • [新手课堂] redis优化系列(五)Sentinel 实现原理、常见问题等
    ## 一、Sentinel 实现原理 接下来我们就来看下 Sentinel 的实现原理,主要分为以下三个步骤。 ①、检测问题,主要讲的是三个定时任务,这三个内部的执行任务可以保证出现问题马上让 Sentinel 知道。 ②、发现问题,主要讲的是主观下线和客观下线。当有一台 Sentinel 机器发现问题时,它就会主观对它主观下线,但是当多个 Sentinel 都发现有问题的时候,才会出现客观下线。 ③、找到解决问题的人,主要讲的是领导者选举,如何在 Sentinel 内部多台节点做领导者选举,选出一个领导者。 ④、解决问题,主要讲的是故障转移,即如何进行故障转移。 ### 三个定时任务: 首先要说的是内部 Sentinel 会执行以下三个定时任务。 每10秒每个 Sentinel 对 Master 和 Slave 执行一次 Info Replication。 每2秒每个 Sentinel 通过 Master 节点的 channel 交换信息(pub/sub)。 每1秒每个 Sentinel 对其他 Sentinel 和 Redis 执行 ping。 第1个定时任务,指的是 Redis Sentinel 可以对 Redis 节点做失败判断和故障转移,在 Redis 内部有三个定时任务作为基础,来 Info Replication 发现 Slave 节点,这个命令可以确定主从关系。 第2个定时任务,类似于发布订阅,Sentinel 会对主从关系进行判定,通过 _sentinel_:hello 频道交互。了解主从关系可以帮助更好的自动化操作 Redis。然后 Sentinel 会告知系统消息给其它 Sentinel 节点,最终达到共识,同时 Sentinel 节点能够互相感知到对方。 第3个定时任务,指的是对每个节点和其它 Sentinel 进行心跳检测,它是失败判定的依据。 ### 主观下线和客观下线: 回顾一下 Sentinel 的配置。 sentinel monitor mymaster 127.0.0.1 6379 2 sentinel down-after-milliseconds mymaster 30000 Sentinel 会 ping 每个节点,如果超过30秒,依然没有回复的话,做下线的判断。 **那么什么是主观下线呢?** 每个 Sentinel 节点对 Redis 节点失败的“偏见”。之所以是偏见,只是因为某一台机器30秒内没有得到回复。 **那么如何做到客观下线呢?** 这个时候需要所有 Sentinel 节点都发现它30秒内无回复,才会达到共识。 ### 领导者选举方式: ①、每个做主观下线的sentinel节点,会向其他的sentinel节点发送命令,要求将它设置成为领导者 ②、收到命令sentinel节点,如果没有同意通过其它节点发送的命令,那么就会同意请求,否则就会拒绝 ③、如果sentinel节点发现自己票数超过半数,同时也超过了sentinel monitor mymaster 127.0.0.1 6379 2 超过2个的时候,就会成为领导者 ④、进行故障转移操作 ### 如何选择“合适的”Slave 节点: Redis 内部其实是有一个优先级配置的,在配置文件中 slave-priority,这个参数是 Salve 节点的优先级配置,如果存在则返回,如果不存在则继续。 当上面这个优先级不满足的时候,Redis 还会选择复制偏移量最大的 Slave节点,如果存在则返回,如果不存在则继续。之所以选择偏移量最大,这是因为偏移量越小,和 Master 的数据越不接近,现在 Master挂掉了,说明这个偏移量小的机器数据也可能存在问题,这就是为什么要选偏移量最大的 Slave 的原因。 如果发现偏移量都一样,这个时候 Redis 会默认选择 runid 最小的节点。 ## 二、生产环境中部署技巧 1)Sentinel 节点不应该部署在一台物理“机器”上。 这里特意强调物理机是因为一台物理机做成了若干虚拟机或者现今比较流行的容器,它们虽然有不同的 IP 地址,但实际上它们都是同一台物理机,同一台物理机意味着如果这台机器有什么硬件故障,所有的虚拟机都会受到影响,为了实现 Sentinel 节点集合真正的高可用,请勿将 Sentinel 节点部署在同一台物理机器上。 2)部署至少三个且奇数个的 Sentinel 节点。 3个以上是通过增加 Sentinel 节点的个数提高对于故障判定的准确性,因为领导者选举需要至少一半加1个节点,奇数个节点可以在满足该条件的基础上节省一个节点。 ## 三、哨兵常见问题 哨兵集群在发现 master 节点挂掉后会进行故障转移,也就是启动其中一个slave 节点为master 节点。在这过程中,可能会导致数据丢失的情况。 ### 1、异步复制导致数据丢失 因为master->slave的复制是异步,所以可能有部分还没来得及复制到slave就宕机了,此时这些部分数据就丢失了。 在异步复制的过程当中,通过min-slaves-max-lag这个配置,就可以确保的说,一旦slave复制数据和ack延迟时间太长,就认为可能master宕机后损失的数据太多了,那么就拒绝写请求,这样就可以把master宕机时由于部分数据未同步到slave导致的数据丢失降低到可控范围内。 ### 2、集群脑裂导致数据丢失 脑裂:也就是说,某个master所在机器突然脱离了正常的网络,跟其它slave机器不能连接,但是实际上master还运行着。** **造成的问题:** 此时哨兵可能就会认为master宕机了,然后开始选举,将其它slave切换成master。这时候集群里就会有2个master,也就是所谓的脑裂。** 此时虽然某个slave被切换成了master,但是可能client还没来得及切换成新的master,还继续写向旧的master的数据可能就丢失了。 因此旧master再次恢复的时候,会被作为一个slave挂到新的master上去,自己的数据会被清空,重新从新的master复制数据。 **如何怎么解决?** min-slaves-to-write 1 min-slaves-max-lag 10 要求至少有1个slave,数据复制和同步的延迟不能超过10秒 如果说一旦所有的slave,数据复制和同步的延迟都超过了10秒钟,那么这个时候,master就不会再接收任何请求了 上面两个配置可以减少异步复制和脑裂导致的数据丢失 集群脑裂因为client还没来得及切换成新的master,还继续写向旧的master的数据可能就丢失了通过min-slaves-to-write 确保必须是有多少个从节点连接,并且延迟时间小于min-slaves-max-lag多少秒。 ### 当然对于客户端需要怎么做呢? 对于client来讲,就需要做些处理,比如先将数据缓存到内存当中,然后过一段时间处理,或者连接失败,接收到错误切换新的master处理。
  • [问题求助] 鲲鹏服务器搭建redis集群遇到的一些问题
    【功能模块】配置修改好各单节点的配置文件redis.conf【操作步骤&问题现象】1、启动节点时启动失败,一直停留在一个状态。【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [问题求助] 在docker中安装Redis遇见的一些问题。
    【功能模块】【操作步骤&问题现象】1、顺利安装Docker与下载redis最新版本镜像后运行容器2、 docker run -d --name redis-chai -p 6379:6379 redis3、4、但是:5、查看工作路径时报错【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [新手课堂] 鲲鹏redis 优化系列(二)Redis 主从原理、主从常用配置
    ## 一、主从复制原理 主从复制过程大体可以分为3个阶段:连接建立阶段(即准备阶段)、数据同步阶段、命令传播阶段。 在从节点执行 slaveof 命令后,复制过程便开始运作,下面图示大概可以看到,从图中可以看出复制过程大致分为6个过程 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/23/1650690907187592317.png) 主从配置之后的日志记录也可以看出这个流程(看主redis或从redis日志都可以): ```shell vi` `/var/log/redis/redis``.log ``` ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/23/1650690930349391190.png) **1)保存主节点(master)信息:** 执行 slaveof 后 Redis 会打印如下日志: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/23/1650691125018436230.png) **2)从节点(slave)底层内部通过每秒运行的定时任务维护复制相关逻辑,当定时任务发现存在新的主节点后,会尝试与该节点建立网络连接** 从节点与主节点建立网络连接示例图: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/23/1650690949097406685.png) 从节点会建立一个 socket 套接字,从节点建立了一个端口为51234的套接字,专门用于接受主节点发送的复制命令。从节点连接成功后打印如下日志: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/23/1650690961161482232.png) 如果从节点无法建立连接,定时任务会无限重试直到连接成功或者手动执行 slaveof no one 取消复制(断开主从) 注:对一个从redis节点服务器执行命令 slaveof no one 将使得这个从redis节点服务器关闭复制功能,并从 从redis节点服务器转变回主redis节点服务器,原来同步所得的数据集不会被丢弃。 关于连接失败,可以在从节点执行 info replication 查看 master_link_down_since_seconds 指标,它会记录与主节点连接失败的系统时间。从节点连接主节点失败时也会每秒打印如下日志,方便发现问题: \# Error condition on socket for SYNC: {socket_error_reason} **3)发送 ping 命令** 连接建立成功后从节点发送 ping 请求进行首次通信,ping 请求主要目的如下:** ** ①、检测主从之间网络套接字是否可用。 ②、检测主节点当前是否可接受处理命令。 ③、如果发送 ping 命令后,从节点没有收到主节点的 pong 回复或者超时,比如网络超时或者主节点正在阻塞无法响应命令,从节点会断开复制连接,下次定时任务会发起重连。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/23/1650690983993721130.png) 从节点发送的 ping 命令成功返回,Redis 打印如下日志,并继续后续复制流程: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/23/1650690994108423555.png) **4)权限验证。**如果主节点设置了 requirepass 参数,则需要密码验证,从节点必须配置 masterauth 参数保证与主节点相同的密码才能通过验证;如果验证失败复制将终止,从节点重新发起复制流程。 **5)同步数据集。**主从复制连接正常通信后,对于首次建立复制的场景,主节点会把持有的数据全部发送给从节点,这部分操作是耗时最长的步骤。 ** ** **6)命令持续复制。**当主节点把当前的数据同步给从节点后,便完成了复制的建立流程。接下来主节点会持续地把写命令发送给从节点,保证主从数据一致性。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/23/1650691009544915779.png) ## 二、全量复制和部分复制 ### 2.1 相关概念 **全量复制**:用于初次复制或其它无法进行部分复制的情况,将主节点中的所有数据都发送给从节点,是一个非常重型的操作,当数据量较大时,会对主从节点和网络造成很大的开销 **部分复制**:用于处理在主从复制中因网络闪断等原因造成的数据丢失场景,当从节点再次连上主节点后,(如果条件允许,后面会说到具体那些条件需要被满足),主节点会补发丢失数据给从节点。因为补发的数据远远小于全量数据,可以有效避免全量复制的过高开销,需要注意的是,如果网络中断时间过长,造成主节点没有能够完整地保存中断期间执行的写命令,则无法进行部分复制,仍使用全量复制 **复制偏移量**:参与复制的主从节点都会维护自身复制偏移量。主节点(master)在处理完写入命令后,会把命令的字节长度做累加记录,统计信息在 info replication 中的 master_repl_offset 指标中: 提醒:记得进入redis客户端执行该命令 ```shell #在从节点的redis中执行以下命令``redis-cli``info replication ``` 截图如下: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/23/1650691021593127602.png) 从节点(slave)每秒钟上报自身的复制偏移量给主节点,因此主节点也会保存从节点的复制偏移量,统计指标如下: 再次提醒:记得进入redis客户端执行 info replication 命令 ```shell #在主节点的redis中执行以下命令``redis-cli``info replication ``` 截图如下: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/23/1650691032668477158.png) 从节点在接收到主节点发送的命令后,也会累加记录自身的偏移量。统计信息在 info replication 中的 slave_repl_offset 中 **复制积压缓冲区**:复制积压缓冲区是保存在主节点上的一个固定长度的队列,默认大小为1MB(可以调整大小,具体调整多大看各自需求业务来调整),当主节点有连接的从节点(slave)时被创建,这时主节点(master)响应写命令时,不但会把命令发送给从节点,还会写入复制积压缓冲区。 在命令传播阶段(也可以说是 同步数据阶段),主节点除了将写命令发送给从节点,还会发送一份给复制积压缓冲区,作为写命令的备份;除了存储写命令,复制积压缓冲区中还存储了其中的每个字节对应的复制偏移量(offset) 。由于复制积压缓冲区定长而且先进先出,所以它保存的是主节点最近执行的写命令;时间较早的写命令会被挤出缓冲区。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/23/1650691043448469640.png) ### 2.2 Redis全量复制的过程如下图所示: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/23/1650691051553245985.png) 如上图所示: 1、Redis 内部会发出一个同步命令,刚开始是 Psync 命令,Psync ? -1表示要求 master 主机同步数据 2、主机会向从机发送 runid 和 offset,因为 slave 并没有对应的 offset,所以是全量复制 3、从机 slave 会保存 主机 master 的基本信息 save masterInfo 4、主节点收到全量复制的命令后,执行 bgsave 命令(异步执行),在后台生成RDB文件(快照文件),并使用一个缓冲区(称为复制缓冲区)记录从现在开始执行的所有写命令 5、主机发送 RDB 文件给从机 6、主机发送缓冲区数据到从机 7、刷新旧的数据,从节点在载入主节点的数据之前要先将老数据清除 8、加载 RDB 文件将数据库状态更新至主节点执行bgsave时的数据库状态和缓冲区数据的加载。 **全量复制开销,主要有以下几项:** 1、bgsave 时间 2、RDB 文件网络传输时间 3、从节点清空数据的时间 4、从节点加载 RDB 的时间 注:生成一个几GB 十几GB的RDB快照文件 大概是需要2-5分钟的样子 ### 2.3 部分复制(又称 增量复制) 部分复制是 Redis 2.8 以后出现的,之所以要加入部分复制,是因为全量复制会产生很多问题,比如像上面的时间开销大、无法隔离等问题, Redis 希望能够在 master 出现抖动(相当于断开连接)的时候,可以有一些机制将复制的损失降低到最低。 部分复制的过程如下图所示: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/23/1650691067400274764.png) 如上图所示: 1、如果网络抖动(连接断开 connection lost) 2、主机 master 还是会写 replbackbuffer(复制缓冲区) 3、从机 slave 会继续尝试连接主机 4、从机 slave 会把自己当前 runid 和偏移量传输给主机 master,并且执行 pysnc 命令同步 5、如果 master 发现从节点的偏移量是在缓冲区的范围内,就会返回 continue(在指的是继续复制的意思) 命令,如果从节点的偏移量不在缓冲区的范围之内,就不会进行部分复制操作了,这样就意味着它会执行全量复制,所以我们要尽量避免这种情况的发生。 6、同步了 offset 的部分数据,所以部分复制的基础就是偏移量 offset **正常情况下redis是如何决定是全量复制还是部分复制?** 从节点将offset(偏移量)发送给主节点后,主节点根据offset(偏移量)和缓冲区大小决定能否执行部分复制; 如果offset偏移量之后的数据,仍然都在复制积压缓冲区里,则执行部分复制; 如果offset偏移量之后的数据已不在复制积压缓冲区中(数据已被挤出),则执行全量复制; **缓冲区大小调节:** 由于缓冲区长度固定且有限,因此可以备份的写命令也有限,当主从节点offset的差距过大超过缓冲区长度时,将无法执行部分复制,只能执行全量复制。反过来说,为了提高网络中断时部分复制执行的概率,可以根据需要增大复制积压缓冲区的大小(通过配置repl-backlog-size)来设置;例如如果网络中断的平均时间是60s,而主节点平均每秒产生的写命令(特定协议格式)所占的字节数为100KB,则复制积压缓冲区的平均需求为6MB,保险起见,可以设置为12MB,来保证绝大多数断线情况都可以使用部分复制。 **服务器运行ID(runid):** 每个Redis节点(无论主从),在启动时都会自动生成一个随机ID(每次启动都不一样),由40个随机的十六进制字符组成;runid用来唯一识别一个Redis节点。 通过info server命令,可以查看节点的runid:** ** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/23/1650691083518233283.png) 主从节点初次复制时,主节点将自己的runid发送给从节点,从节点将这个runid保存起来;当断线重连时,从节点会将这个runid发送给主节点;主节点根据runid判断能否进行部分复制: 如果从节点保存的runid与主节点现在的runid相同,说明主从节点之前同步过,主节点会继续尝试使用部分复制(到底能不能部分复制还要看offset和复制积压缓冲区的情况) 如果从节点保存的runid与主节点现在的runid不同,说明从节点在断线前同步的Redis节点并不是当前的主节点,只能进行全量复制。 ## 三、主从复制的常用相关配置 **1、从redis节点配置:** ①、slaveof slave实例需要配置该项,指向master的(ip, port) ②、masterauth 如果master实例启用了密码保护,则该配置项需填master的启动密码,若master未启用密码,该配置项需要注释掉 ③、slave-serve-stale-data 指定slave与master连接中断时的动作。默认为yes,表明slave会继续应答来自client的请求,但这些数据可能已经过期(因为连接中断导致无法从master同步)。若配置为no,则slave除正常应答"INFO"和"SLAVEOF"命令外,其余来自客户端的请求命令均会得到"SYNC with master in progress"的应答,直到该slave与master的连接重建成功或该slave被提升为master ④、slave-read-only 指定slave是否只读,默认为yes。若配置为no,这表示slave是可写的,但写的内容在主从同步完成后会被删掉 ⑤、repl-disable-tcp-nodelay 指定向slave同步数据时,是否禁用socket的NO_DELAY选项。若配置为yes,则禁用NO_DELAY,则TCP协议栈会合并小包统一发送,这样可以减少主从节点间的包数量并节省带宽,但会增加数据同步到slave的时间。若配置为no,表明启用NO_DELAY,则TCP协议栈不会延迟小包的发送时机,这样数据同步的延时会减少,但需要更大的带宽。通常情况下,应该配置为no以降低同步延时,但在主从节点间网络负载已经很高的情况下,可以配置为yes 注:主从节点进行数据传输是基于tcp协议进行传输的 ⑥、slave-priority 指定slave的优先级。在不只1个slave存在的部署环境下,当master宕机时,Redis Sentinel会将priority值最小的slave提升为master。需要注意的是,若该配置项为0,则对应的slave永远不会被Redis Sentinel自动提升为master
总条数:310 到第
上滑加载中