redis-cli连接集群 redis连接集群命令

莫娜号 1

redis集群方案有哪些

Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个负责一部分hash槽,举个例子,比如当前集群有3个,那么:

Redis数据量日益增大,而且使用的公司越来越多,不仅用于做缓存,同时趋向于存储这块,这样必促使集群的发展,各个公司也在收集适合自己的集群方案,目前行业用的比较多的是下面几种集群架构,大部分都是采用分片技术,解决单实例内存增大带来的一系列问题。

redis-cli连接集群 redis连接集群命令redis-cli连接集群 redis连接集群命令


redis-cli连接集群 redis连接集群命令


本篇文章简单介绍五种方案:

cluster方案

twemproxy方案

哨兵模式

codis

客户端分片

cluser方案

从redis 3.0版本开始支持redis-cluster集群,redis-cluster采用无中心结构,每个保存数据和整个集群状态,每个都和其他连接。redis-cluster是一种服务端分片技术。

redis-cluster架构图

redis-cluster特点:

每个都和n-1个通信,这被称为集群总线(cluster bus)。它们使用特殊的端口号,即对外服务端口号加10000。所以要维护好这个集群的每个信息,不然会导致整个集群不可用,其内部采用特殊的二进制协议优化传输速度和带宽。

redis-cluster把所有的物理映射到[0,16383]slot(槽)上,cluster负责维护node--slot--value。

集群预分好16384个桶,当需要在redis集群中插入数据时,根据CRC16(KEY) mod 16384的值,决定将一个key放到哪个桶中。

客户端与redis直连,不需要连接集群所有的,连接集群中任何一个可用即可。

redis-trib.rb脚本(rub语言)为集群的管理工具,比如自动添加,规划槽位,迁移数据等一系列作。

的fail是通过集群中超过半数的检测失效时才生效。

整个cluster被看做是一个整体,客户端可连接任意一个进行作,当客户端作的key没有分配在该上时,redis会返回转向指令,指向正确的。

为了增加集群的可访问性,的方案是将node配置成主从结构,即一个主,挂n个sle从。如果主失效,redis cluster会根据选举算法从sle中选择一个上升为,整个集群继续对外提供服务。

twemproxy方案

twemproxy架构图:

Redis中间件twemproxy是一种利用中间件做分片的技术。twemproxy处于客户端和的中间,将客户端发来的请求,进行一定的处理后(sharding),再转发给后端真正的redis。也就是说,客户端不直接访问redis,而是通过twemproxy中间件间接访问。降低了客户端直连后端的连接数量,并且支持集群水平扩展。

twemproxy中间件的内部处理是无状态的,它本身可以很轻松地集群,这样可以at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.ja:106)避免单点压力或故障。

twemproxy又称nutcracker,起源于推特系统中redis、memcached集群的轻量级。

Github源码地址(

从上面架构图看到twemproxy是一个单点,很容易对其造成很大的压力,所以通常会结合keepalived来实现twemproy的高可用。这时,通常只有一台twemproxy在工作,另外一台处于备机,当一台挂掉以后,vip自动漂移,备机接替工作。关于keepalived的用法可自行网上查阅资料。

哨兵模式

Sentinel哨兵

在1掉线后:

升级2为新的主:

每个Sentinel以每秒钟一次的频率向它所知的Master、Sle以及其他Sentinel实例发送一个PING命令。

当有足够数量的Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态,则Master会被标记为客观下线。

在一般情况下,每个Sentinel会以每10秒一次的频率向它所知的所有Master、Sle发送INFO命令。

当Master被Sentinel标记为客观下线时,Sentinel向下线的Master的所有Sle发送INFO命令的频率会从10秒一次改为每秒一次。

若没有足够数量的Sentinel同意Master已经下线,Master的客观下线状态就会被移除。若Master重新向Sentinel的PING命令返回有效值,Master的主观下线状态就会被移除。

codis

codis是一个分布式的Redis解决方案,由豌豆荚开源,对于上层的应用来说,连接codis proxy和连接原生的redis server没什么明显的区别,上层应用可以像使用单机的redis一样使用,codis底层会处理请求的转发,不停机的数据迁移等工作,所有后边的事情,对于前面的客户端来说是透明的,可以简单的认为后边连接的是一个内存无限大的redis服务。

客户端分片

分区的逻辑在客户端实现,由客户端自己选择请求到哪个。方案可参考一致性哈希,这种方案通常适用于用户对客户端的行为有完全控制能力的场景。

总结:没有的方案,只有最合适的方案。

更多Redis相关技术文章,请访问Redis教程栏目进行学习!

集群redis哨兵模式连接方式,解决database不生效问题(附源码)

注意事项:

1 引入pom依Z1仍然能够向主B中写入, 如果网络分区发生时间较短,那么集群将会继续正常运作,如果分区的时间足够让大部分的一方将B1选举为新的,那么Z1写入B中得数据便丢失了.赖

2 添加redis哨兵配置,database主动设置,才会生效

3 applicatio如果一个实例距离一次有效回复PING命令的时间超过down-after-milliseconds选项所指定的值,则这个实例会被Sentinel标记为主观下线。n.yml配置

5 启动测试连接

可以看到redis.clients.jedis.JedisSentinelPool : Created JedisSentinelPool to at 10.10.195.249:6379已经启动了

作为程序员第 140 篇文章,每次写一句歌词记录一下,看看人生有几首歌的时间,wahahaha ...

redis连不上咋整??

在redis-cli命令行使用: clients可以查看当前的redis连接数。

如果 Redis 连不上,可能是以下原因之一:

4 项目目录

Redis 服务未启动:请检查 Redis 服务是否已经启动。可以使用 `ps -ef | grep redis` 命令查看 Redis 进程是否在运行。

Redis 配置错误:请检查 Redis 配置文件是否正确。可以使用 `redis-cli config get bind` 命令查看 Redis 绑定的 IP 地址是否正确。

网络问题:请检查网络连接是否正常。可以使用 `ping` 命令测试 Redis 是否能够正常访问。

防火墙问题:请检查防火墙设置是否正确。如果 Redis 和客户端在不同的网络中,可能需要在防火墙中开放 Redis 端口。

如果您已经确认 Redis 服务已经启动,并且配置、网络和防火墙设置都正确,但仍然无法连接 Redis,可以尝试以下方法:

检查 Redis 日志:Redis 日志中可能会记录连接错误的详细信息。可以查看 Redis 日志文件,找到相关的错误信息。

检查 Redis 版本:请确保 Redis 客户端和使用的是相同的 Redis 版本。如果版本不一致,可能会导致连接错误。

检查 Redis 密码:如果 Redis 设置了密码,客户端需要提供正确的密码才能连接。请检查客户端是否提供了正确的密码。

检查 Redis 端口:请确保客户端使用的 Redis 端口与配置的端口一致。可以使用 `redis-cli -h -p

` 命令测试连接。

如果您仍然无法解决连接问题,请提供更多详细信息,我会尽力帮助您解决问题。

Docker环境下创建Redis集群出现ERR Invalid node address specified: redis1:6379错误

at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.ja:67)

利用Docker 的swarm模式创建6个redis服务,在容器内可以相互ping通。利用容器名称创建redis集群里报 ERR Invalid node address specified: redis1:6379错误。

查找资料发现是redist的一些限制,Protected mode is a layer of security protection, in order to oid that

解决方法

把容器名称改在IP地址即可解决。

原因

玩转Redis的高可用(主从、哨兵、集群)

at ja.DualStackPlainSocketImpl.waitForConnect(Native Mod)

所谓的高可用,也叫 HA(High Availability),是分布式系统架构设计中必须考虑的因素之一,它是保证系统SLA的重要指标。Redis 高可用的主要有三种模式: 主从模式 , 哨兵模式和集群模式 。

Redis 提供了 Redis 提供了(replication)功能,当一台 redis 数据库中的数据发生了变化,这个变化会被自动地同步到其他的 redis 机器上去。

Redis 多机器部署时,这些机器会被分成两类,一类是主( ),一类是从(sle )。一般 主可以进行读、写作 ,而 从只能进行读作 。一个主可以有多个从,但是一个从只会有一个主,也就是所谓的 一主多从结构 。

· 支持主从,主机会自动将数据同步到从机,可以进行读写分离;

· Master 是以非阻塞的方式为主 Sles 提供服务。所以在 Master-Sle 同步期间,客户端仍然可以提交查询或修改请求;

· Sle 同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis 则返回同步之前的数据。

· Redis 不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的 IP 才能恢复;

· 主机宕机,宕机前有部分数据未能及时同步到从机,切换 IP 后面还会引入数据不一致的问题,降低了系统的可用性;

· Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂;

· Redis 的主和从中的数据是一样的,降低的内存的可用性

实际生产中,我们优先考虑哨兵模式。这种模式下, 宕机,哨兵会自动选举 并将其他的 sle 指向新的 。

在主从模式下,redis 同时提供了哨兵命令 redis-sentinel ,哨兵是一个的进程,作为进程,它会运行。其原理是哨兵进程向所有的 redis 机器人发送命令,等待 Redis 响应,从而运行的多个 Redis 实例。一般为了便于决策选举,使用 奇数个哨兵 。多个哨兵构成一个哨兵集群,哨兵直接也会相互通信,检查哨兵是否正常运行,同时发现 战机哨兵之间会进行决策选举新的

哨兵模式的作用:

· 通过发送命令,让 Redis 返回其运行状态,包括主和从;

· 然而一个哨兵进程对 Redis 进行,也可能会出现问题,为此,我们可以使用多个哨兵进行。各个哨兵之间还会进行,这样就形成了多种哨兵模式。

哨兵很像 kafka 集群中的 zookeeper 的功能。

· 哨兵模式是基于主从模式的,所有主从的优点,哨兵模式都具有。

· 主从可以自动切换,系统更健壮,可用性更高。

· 具有主从模式的缺点,每台机器上的数据是一样的,内存的可用性较低。

· Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。

Redis 集群模式本身没有使用一致性 hash 算法,而是使用 slots 插槽 。

Redis 哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台 Redis 都存储相同的数据,很浪费内存,所以在 redis3.0 上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,对数据进行分片,也就是说每台 Redis 上存储不同的内容;每个都会通过集群总线(cluster bus),与其他的进行通信。 通讯时使用特殊的端口号,即对外服务端口号加 10000。例如如果某个 node 的端口号是 6379,那么它与其它 nodes 通信的端口号是 16379。nodes 之间的通信采用特殊的二进制协议。

对客户端来说,整个 cluster 被看做是一个整体,客户端可以连接任意一个 node 进行作,就像作单一 Redis 实例一样, 当客户端作的时候 key 没有分配到该 node 上时,Redis 会返回转向指令,指向正确的 node,这有点儿像浏览器页面的 302 redirect 跳转。

根据,集群部署至少要 3 台以上的 ,使用 3 主 3 从六个的模式。

在 Redis 的每一个上,都有这么两个东西, 一个是插槽(slot),它的的取值范围是:0-16383, 可以从上面 redis-trib.rb 执行的结果看到这 16383 个 slot 在三个 上的分布。还有一个就是 cluster,可以理解为是一个集群管理的插件,类似的哨兵。

当我们的存取的 Key 到达的时候,Redis 会根据 crc16 的算法对计算后得出一个结果,然后把结果和 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的,然后直接自动跳转到这个对应的上进行存取作。

如果 1 和它的从 sle 1 都宕机了,整个集群就会进入 fail 状态,因为集群的 slot 映射不完整。 如果集群超过半数以上的 挂掉,无论是否有 sle,集群都会进入 fail 状态。

redis-cluster 采用去中心化的思想 ,没有中心的说法,客户端与 Redis 直连,不需要中间层,客户端不需要连接集群所有,连接集群中任何一个可用即可。

对 redis 集群的扩容就是向集群中添加机器,缩容就是从集群中删除机器,并重新将 16383 个 slots 分配到集群中的上(数据迁移)。

扩缩容也是使用集群管理工具 redis-tri.rb。

扩容时,先使用 redis-tri.rb add-node 将新的机器加到集群中,这是新机器虽然已经在集群中了,但是没有分配 slots,依然是不起做用的。在使用 redis-tri.rb reshard 进行分片重哈希(数据迁移),将旧上的 slots 分配到新上后,新才能起作用。

缩容时,先要使用 redis-tri.rb reshard 移除的机器上的 slots,然后使用 redis-tri.rb add-del 移除机器。

采用去中心化思想,数据按照 slot 存储分布在多个,间数据共享,可动态调整数据分布;

可扩展性:可线性扩展到 1000 多个,可动态添加或删除;

高注意:需要在 Redis 上正确配置连接数,否则 INFO 命令返回的信息中可能没有相应的连接池信息。可用性:部分不可用时,集群仍可用。通过增加 Sle 做 standby 数据副本,能够实现故障自动 failover,之间通过 gossip 协议交换状态信息,用投票机制完成 Sle 到 Master 的角色提升;

降低运维成本,提高系统的扩展性和可用性。

1.Redis Cluster 是无中心的集群架构,依靠 Goss 协议(谣言传播)协同自动化修复集群的状态。但 GosSIp 有消息延时和消息冗余的问题,在集群数量过多的时候,之间需要不断进行 PING/PANG 通讯,不必须要的流量占用了大量的网络资源。虽然 Reds4.0 对此进行了优化,但这个问题仍然存在。

2.数据迁移问题

Redis Cluster 可以进行的动态扩容缩容,这一过程,在目前实现中,还处于半自动状态,需要人工介入。在扩缩容的时候,需要进行数据迁移。

而 Redis 为了保证迁移的一致性,迁移所有作都是同步作 ,执行迁移时,两端的 Redis 均会进入时长不等的阻塞状态,对于小 Key,该时间可以忽略不计,但如果一旦 Key 的内存使用过大,的时候会接触发集群内的故障转移,造成不必要的切换。

主从模式: 挂掉后,需要手动指定新的 ,可用性不高,基本不用。

哨兵模式: 挂掉后,哨兵进程会主动选举新的 ,可用性高,但是每个存储的数据是一样的,浪费内存空间。数据量不是很多,集群规模不是很大,需要自动容错容灾的时候使用。

集群模式:数据量比较大,QPS 要求较高的时候使用。 Redis Cluster 是 Redis 3.0 以后才正式推出,时间较晚,目前能证明在大规模生产环境下成功的案例还不是很多,需要时间检验。

AIX系统怎么查redis连接池连接数?

Sentinel(哨兵)是Redis的高可用性解决方案:由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主以及这些主下的所有从,并在被监视的主进入下线状态时,自动将下线主属下的某个从升级为新的主。

在 AIX 系统中查看 Redis 连接池连接数,可以通过连接 Redis 的客户端工具执行 INFO 命令,获取 Redis 的信息,其中包括连接池的相关信息。具体步骤如下:

在 AIX 系统为了保证高可用, redis-cluster 集群引入了主从模式 ,一个主对应一个或者多个从。当其它主 ping 主 1 时,如果半数以上的主与 1 通信超时,那么认为 1 宕机了,就会启用 1 的从 sle 1,将 sle 1 变成主继续提供服务。中安装 Redis 的客户端工具,比如 redis-cli。

通过 redis-cli 连接 Redis 。

执行 INFO 命令,获取 Redis 的信息。命令格式如下:

查看返回的信息中关于连接池的部分,其中包括连接数、当前连接数等相关信息。可以通过搜索 "maxclients" 来找到连接数的配置。

连接远程的redis 集群报Could not get a resource from the pool异常

at ja.Socket.connect(Socket.ja:589)

在阿里云Ubuntu新搭建的redis集群,始终无法连接,报Could not get a resource from the pool异常

所以将redis.conf中的protected-mode yes改为protected-mode no

重启redis实例,以为问Copy codeINFO题就解决了?发现还是报Could not get a resource from the pool异常

这个是什么情况,要逆天嘛?

查看redis node信息看一下,终于发现了问题

怎么会有172的IP,到这里终于找到问题根源了,修改node.conf配置,重启redis,问题终于解决。

如何查看redis连接数

ZooKeeper 会一直保存当前有效的 主从实例 IP:Port 信息。至于主从自动切换过程,使用 redis 自带的 sentinel 实现,现设置为超过 30s 主 server 无响应,则由 sentinel 进行主从实例的切换,切换后就会触发以主、从实例通过以上提到的一系列动作,从而完成最终的切换。

如下图:

出现这个问题的原因是redis-cli对设别机器名支持不的够好。

config get maxclients 可以查询redis允许的连接数。

如下图:

client list ——查看详细

clients ——查看连接数等信息

Redis集群方案应该怎么做

当某个 slot 从 online 变成 pre_migrate 后,客户端会删除 clients 下的 uid 临时,然后在M igrating s 创建 uid 临时。注意,因为需要保证数据不丢失,从 pre_migrate 到 migrating 期间,这个 slot 是被锁定的,即所有对这个 slot 的读写都会被阻塞。所以 mananger 会最多等待 10s ,确认所有客户端都已经切换到准备就绪状态,如果发现某个客户端一直未准备就绪,那么 mananger 会放弃此次迁移,把 slot 状态由 pre_migrate 改为 online 。如果客户端发现 slot 状态由 pre_migrate 变成 online 了,那么会删除 migrating_clients 下的 uid ,在 clients 下重新创建 uid 。还需要注意的一点是,有可能一个客户刚启动,并且正在往 clients 下创建 uid ,但是因为网络延迟还没创建完成,导致 mar 未确认到这个 client 是否准备就绪,所以 mananger 把 slot 改为 pre_migrate 后会等待 1s 再确认所有客户端是否准备就绪。

以Ja语言为例,简单说一下,除了一些公司自主开发的集群外。常用的解决高并发问题的集群一般有三种:

Migrating 是 mar 确认了所有客户端都已经做好迁移准备后,在 dst 写入此分片需要迁移的目标 group 。待迁移完成,会在 src 写入目标 group_name , dst 设为空, stats 设为 online 。

使用redis-trib.rb,这个是安装redis时就自带的一种集群,采用了服务端分片的方式,支持主备,此集群既解决了高并发的问题,也解决了高可用的问题。Jedis使用JedisCluster类来访问。

使用Jedis带的客户端分片ShardedJedisPool类。

使用进行分片twemproxy,连接可以使用Jedis类(单链接)和JedisPool类(多链接)。

通过Redis的sentinel机制还可以配置高可用集群,一主多从,主down掉后,sentinel负责选拔一个从机作为新的主机。

如果有什么疑问,可以留言。

jedis连接集群报Could not get a resource from the pool错误

Sentinel的工作方式

Caused by: org.springframework.data.redis.RedisConnectionFailureException: Could not get a resource from the pool; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool

Sentinel : redis 自带的主从切换工具,我们通过 sentinel 实现集群高可用。

at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.ja:41)

at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.ja:37)

at org.springframework.data.redis.connection.jedis.JedisClusterConnection.convertJedisAccessException(JedisClusterConnection.ja:3999)

at org.springframework.data.redis.connection.jedis.JedisClusterConnection.setEx(JedisClusterConnection.ja:717)

at org.springframework.data.redis.core.DefaultValueOperations 11.doInRedis(DefaultValueOperations.ja:186)

at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.ja:207)

at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.ja:169)

at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.ja:)

at org.springframework.data.redis.core.DefaultValueOperations.set(DefaultValueOperations.ja:182)

at io.renrenmon.utils.SuppleDataUtils.provideIcc(SuppleDataUtils.ja:107)

at io.renren.modules.job.task.TaskIcc.taskFour(TaskIcc.ja:242)

... 10 common frames omitted

Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool

at redis.clients.util.Pool.getResource(Pool.ja:53)

at redis.clients.jedis.JedisPool.getResource(JedisPool.ja:226)

at redis.clients.jedis.JedisSlotBasedConnectionHandler.getConnectionFromSlot(JedisSlotBasedConnectionHandler.ja:66)

at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.ja:116)

at redis.clients.jedis.JedisClusterCommand.runBinary(JedisClusterCommand.ja:60)

at redis.clients.jedis.BinaryJedisCluster.setex(BinaryJedisCluster.ja:268)

at org.springframework.data.redis.connection.jedis.JedisClusterConnection.setEx(JedisClusterConnection.ja:715)

... 18 common frames omitted

Caused by: redis.clients.jedis.exceptions.JedisConnectionException: ja.SocketTimeoutException: connect timed out

at redis.clients.jedis.Connection.connect(Connection.ja:207)

at redis.clients.jedis.Binary.connect(Binary.ja:93)

at redis.clients.jedis.BinaryJedis.connect(BinaryJedis.ja:1767)

at org.apachemons.pool2.impl.GenericObjectPool.create(GenericObjectPool.ja:868)

at org.apachemons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.ja:435)

at org.apachemons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.ja:363)

at redis.clients.util.Pool.getResource(Pool.ja:49)

... 28 common frames omitted

Caused by: ja.SocketTimeoutException: connect timed out

at ja.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.ja:85)

at ja.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.ja:350)

at ja.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.ja:206)

at ja.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.ja:188)

at ja.PlainSocketImpl.connect(PlainSocketImpl.ja:172)

at ja.SocksSocketImpl.connect(SocksSocketImpl.ja:392)

at redis.clients.jedis.Connection.connect(Connection.ja:184)

... 35 common frames omitted

最近在本地测试通过springboot基础redis的方式连接redis集群,启动的时候没有报错。

到时当执行保存,查询到redis的作的时候,报上面的错误。

首先看到错误信息,先是connect timed out后,再出现的Could not get a resource from the pool错误。一开始排查这个错误,由于使用的是默认连接池,debug的时候,也看到有装载连接池,为啥报错呢。本地通过redis-manger工具,连接集群地址也可以连接访问。从日志也看不出还有其他的错误信息。

于是自己写了main方法直接作JedisCluster的方式来测试,出现的错误跟上面全文一样。用抓包工具wireshark过滤集群的地址,查看连接的消息也是正常的。

另外一个项目使用的reddison客户端,于是测试了deamo用reddison来连接集群地址,启动的时候,发现报如下错误

乖乖,恍然大悟;10.287.17.31地址是的内网地址,本机是连不上内网地址的,只有通过外网地址连接。而我配置的是外网地址。然而,客户端在集群同步和心跳检查的时候,是拉取的集群信息,redis集群信息里面的的信息

配置的是内网地址。客户端就通过这个内网地址来同步信息了。

再次同wireshark过滤集群10.287.17.31,发现有大量的超时重传的包,也没有响应。

最后修改时间:
火炬之光2装备属性随机mod(火炬之光2武器mod)
上一篇
明天会更好歌词完整版带拼音 明天会更好
下一篇

相关文章