900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Redis practise(二)使用Docker部署Redis高可用 分布式集群

Redis practise(二)使用Docker部署Redis高可用 分布式集群

时间:2020-03-26 18:17:31

相关推荐

Redis practise(二)使用Docker部署Redis高可用 分布式集群

思路

鉴于之间学习过的Docker一些基础知识,这次准备部署一个简单的分布式,高可用的redis集群,如下的拓扑

tuopu.png

下面介绍下,对于这张拓扑图而言,需要了解的一些基础概念。

Redis持久化

Redis有两种持久化策略。

Rdb

全量备份形成二进制文件: dump.rdb

在使用命令save(停写),BgSave。或者Save配置条件触发时,开始全量持久化Rdb文件。

相关的Redis.conf配置有:

dirdbfilenamesave(停写)

例如:

save 900 1 #after 900 sec (15 min) if at least 1 key changedsave 300 10 #after 300 sec (5 min) if at least 10 keys changedsave 60 10000 #after 60 sec if at least 10000 keys changeddbfilename dump.rdb # The filename where to dump the DBdir ./ # The DB will be written inside this directory

aof

Append only file增量备份

Redis.conf配置

appendonly yesappendfilename "appendonly.aof" # The name of the append only file (default: "appendonly.aof")

那么aof和Rdb的一些对比呢:

可参考 官方文档

作者:professorLea

链接:/p/ad878b513f9a

來源:简书

简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

Redis高可用

从两个角度来考虑高可用:主从复制,主从切换

主从复制

可以通过命令SLAVEOF,来配置当前节点是某个Redis的Slave节点。参考 slaveof

主从切换

使用官方的Redis-sentinel可以实现Redis的主从切换。

参考Redis官方文档 和 sentinel.md

值得注意的是,配饰抖个Sentinel实例,他们之间是互相通信的。官方推荐:一个健康的集群部署,至少需要3个Sentinel实例。这样他们之间会通过quorum参数来执行主从切换操作ODOWN。

SDOWN:主观离线,Sentinel发现redis挂了。ODOWN:客观离线,Sentinel根据规则投票后确定redis挂了规则为 #of SDOWN>quorum

启动Sentinel

redis-sentinel /path/to/sentinel.conf

在本文的例子中,Sentienl的配置文件如下所示:

sentinel 实例1:

port 26379daemonize yeslogfile "/var/log/redis/sentinel_26379.log"sentinel monitor firstmaster 10.165.124.10 16379 2sentinel auth-pass firstmaster 123456sentinel config-epoch firstmaster 0sentinel leader-epoch firstmaster 0sentinel monitor sencondmaster 10.165.124.10 16381 2sentinel auth-pass sencondmaster 123456sentinel config-epoch sencondmaster 0sentinel leader-epoch sencondmaster 0

sentinel 实例2:

port 26380daemonize yeslogfile "/var/log/redis/sentinel_26380.log"sentinel monitor firstmaster 10.165.124.10 16379 2sentinel auth-pass firstmaster 123456sentinel config-epoch firstmaster 0sentinel leader-epoch firstmaster 0sentinel monitor sencondmaster 10.165.124.10 16381 2sentinel auth-pass sencondmaster 123456sentinel config-epoch sencondmaster 0sentinel leader-epoch sencondmaster 0

sentinel 实例3:

port 26381daemonize yeslogfile "/var/log/redis/sentinel_26381.log"sentinel monitor firstmaster 10.165.124.10 16379 2sentinel auth-pass firstmaster 123456sentinel config-epoch firstmaster 0sentinel leader-epoch firstmaster 0sentinel monitor sencondmaster 10.165.124.10 16381 2sentinel auth-pass sencondmaster 123456sentinel config-epoch sencondmaster 0sentinel leader-epoch sencondmaster 0

可以看出,3个实例监控了 firstmaster及secondmaster,两个集群。

对于其中一个sentinel实例,看到它的信息如下:

$ redis-cli -h 10.165.124.10 -p 26380 -a 12345610.165.124.10:26380> info# Serverredis_version:2.8.24redis_git_sha1:00000000redis_git_dirty:0redis_build_id:7de005b109aa3dd5redis_mode:sentinelos:Linux 3.16.0-0.bpo.4-amd64 x86_64arch_bits:64multiplexing_api:epollgcc_version:4.7.2process_id:28837run_id:630dfd8f09105bc84147923319afbf1d5cebe9a5tcp_port:26380uptime_in_seconds:347096uptime_in_days:4hz:13lru_clock:12213499config_file:/etc/redis/sentinel_26380.conf# Sentinelsentinel_masters:2sentinel_tilt:0sentinel_running_scripts:0sentinel_scripts_queue_length:0master0:name=firstmaster,status=ok,address=10.165.124.10:16379,slaves=1,sentinels=3master1:name=secondmaster,status=ok,address=10.165.124.10:16381,slaves=1,sentinels=3

最后2行可以看出监控的集群,其余2个sentinel实例也是如此。

下面讲,如何在这样的集群上,通过Jedis来进行集群操作

JedisSentinelPool

它解决了痛点:

不确定主redis 的ip port需要从sentinel获取

JedisSentinelPool可以直接想sentinel查询当前master的ip port,在建立连接。

import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPoolConfig;import redis.clients.jedis.JedisSentinelPool;import java.util.HashSet;import java.util.Set;public class JedisSentinelTest {public static Set<String> sentinels = new HashSet<String>();public static JedisPoolConfig config = new JedisPoolConfig();static{config.setMaxTotal(100);config.setMaxIdle(100);config.setMaxWaitMillis(1000);sentinels.add("10.165.124.10:26379");}public static JedisSentinelPool sentinelPool = new JedisSentinelPool("firstmaster", sentinels, config);public static void main(String[] args){Jedis jedis = sentinelPool.getResource();try{jedis.auth("123456");jedis.set("sentinel_one", "sentinel_one");System.out.println(jedis.get("sentinel_one"));}finally {if (jedis!= null){jedis.close();}}}}

从代码里可以看出,我们的Jedis链接是通过Sentinel来获取的。

分布式

解决痛点:

用户较多数据量大,一台服务器内存不足。部署多台增加容量,但是需要考虑如何分割数据

Redis的分布式使用的是一致性哈希算法。满足:

分散性:避免相同的内容映射到不同节点平衡性:均匀分布,每个节点上的内容数量差不多单调性:增删节点时,不影响旧的映射。

一致性哈希的原理如图所示:

haxi.png

可参考:中文介绍,英文介绍

有了算法,那么数据分片在Redis中还有3种分类:

1,客户端分片

使用比如ShardedJedis,Predis,Redis-rb等客户端的包,在客户端金鑫该数据分片。

shardJedis.png

在本例中,使用ShardedJedisPool,代码如下:

public class SharedJedisTest {public static JedisPoolConfig poolConfig = new JedisPoolConfig();public static List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();static {poolConfig.setMaxTotal(100);poolConfig.setMaxIdle(10);poolConfig.setMaxWaitMillis(2000);JedisShardInfo info1 = new JedisShardInfo("10.165.124.10",16379);info1.setPassword("123456");JedisShardInfo info2 = new JedisShardInfo("10.165.124.10",16381);info2.setPassword("123456");shards.add(info1);shards.add(info2);}public static ShardedJedisPool shardedJedisPool = new ShardedJedisPool(poolConfig,shards);public static void main(String[] args){ShardedJedis jedis = null;try {jedis = shardedJedisPool.getResource();for (int i =0; i<50; i++){String key = String.format("key%d",i);String value = String.format("value%d",i);jedis.set(key, value);Client client1= jedis.getShard(key).getClient();System.out.println(String.format(("%s in server: %s, and port is: %d"),key,client1.getHost(),client1.getPort()));}}finally {if (jedis != null){jedis.close();}}}}

可以看出,两个Master都在一个shardedJedisPool里。但是这里有个问题就是需要维护Master的地址,所以后续如果可能,也需要开发Sentinel管理的JedisPool的插件。

2,代理分片

Twemproxy, codis, onecache。如图:

proxy.png

特点:

服务端计算分片,客户端简单客户端无需维护redis的ipProxy会增加响应时间

3,查询路由

Redis 3.0:Redis集群自己做好分片。

特点:

无需proxy客户端可以记录下每个key对应的redis以增加性能支持3.0 的客户端还很少route.png

docker 镜像:

/r/tutum/redis/

/tutumcloud/redis

Redis监控统计

Info {options}

Server/Clients/Memory/Persistence/Stats/Replications/Cpu/Commandstats/Keyspaces

常用的

Memory : used_memory_human 当前使用内存量Memory : mem_fragmentation_ratio 内存碎片率Stats : instantaneous_ops_per_sec 实时的QPSStats: expired_keys, evicted_keys, keyspace_hits, keyspace_misses 过期的key,被置换的key,命中的key数量,未命中的key数量Replication 主从连接是否正常,复制是否正常Commandstats 每个命令的执行情况Keyspaces 每个db上有多少key

彩蛋

一款成功产品的架构图:

单点式: 一主多从

single.png

分布式:

Redis:多个Redis节点,每个节点都一主一从。Redis-sentinel: 主从探获、切换。Proxy:业务代理转发,数据分片NLB:负载均衡,Proxy去单点multi.png

部署Redis的Docker file

FROM tutum/redis:latest# redis configurationENV REDIS_PASS "123456"ENV REDIS_MAXMEMORY_POLICY="allkeys-lru"ENV REDIS_MAXMEMORY="10mb"ENV REDIS_DATABASES="2"ENV REDIS_APPENDONLY="yes"ENV REDIS_APPENDFSYNC=everysec

启动容器:

集群1:

docker run -d --name master1 -p 16379:6379 test/redisdocker run -d --name slave1 -p 16380:6379 -e -e REDIS_MASTERAUTH="123456" test/redis

集群2:

docker run -d --name master2 -p 16381:6379 test/redisdocker run -d --name slave2 -p 16382:6379 -e REDIS_MASTERAUTH="123456" test/redis

作者:professorLea

链接:/p/ad878b513f9a

來源:简书

简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。