详细讲解Redis主从结构配置以及复制原理(一)
来源:互联网 发布:微博短域名 编辑:程序博客网 时间:2024/05/17 22:30
Redis是基于内存的NoSql数据库,同时以其卓越的读写性能闻名业内,并且我在这篇博客Redis持久化机制原理分析与解惑-为什么Redis进行RDB持久化数据时,新起一个进程而不是在原进程中起一个线程中讲过Redis的两种数据持久化方式,但是如果Redis读写压力较大的情况下,将所有的数据都存在一个实例中,这将会大大降低Redis的性能,但是我们可以使用Redis提供的主从复制功能来实现数据冗余和读写分离。
Redis在2.8版本之前,对于从机器每次重连到主都会发送SYNC命令进行全量复制,在2.8版本之后从向主发送PSYNC支持断点续传的复制方式,我们接下来依次看看这两种不同的主从复制方式。
(一)我们先看2.6版本全量主从复制流程:
(1) 从节点起动起来之后主动向主节点发送SYNC命令要求同步数据
(2) 主节点收到SYNC命令之后,fork出一个子进程非阻塞主实例的执行RBD持久化机制,执行完RDB之后将rdb文件发给从节点,
在执行RDB期间主节点将写命令写入缓存,当主节点接到多个从发送SYNC命令之后只执行一次RDB
(3) 从节点收到rdb文件之后载入内存,这个过程从节点可以使用旧数据响应客户端请求,也可以返回一个错误信息
(4) 主节点将缓存中的写命令以Redis命令协议的形式发给从节点
(二)下面先使用版本redis-2.6.16.tar.gz构建一个主从架构
(1)解压 tar zxvf redis-2.6.16.tar.gz
(2)进入到解压后的文件夹redis-2.6.16 执行make命令
(3)复制redis.conf配置文件 为redis_6379.conf、redis_6380.conf、redis_6381.conf
依次修改内容如下:
#主节点配置文件redis_6379.confport 6379#配置log文件logfile master_6379.log#主节点关闭持久化机制#save 900 1#save 300 10#save 60 10000#内存设置为100M,在实际使用中 这里内存实际数值设置要大于实际所需,原因是要为主写命令缓存区预留出空间maxmemory 104857600#从节点配置文件redis_6380.confport 6380#配置log文件logfile slave_6380.logmaxmemory 104857600#设置将该节点设置为 6379端口实例的从节点slaveof 127.0.0.1 6379#从节点配置文件redis_6381.confport 6381#配置log文件logfile slave_6381.logmaxmemory 104857600#设置将该节点设置为 6379端口实例的从节点slaveof 127.0.0.1 6379(4)进入到src目录下依次执行如下命令:
nohup ./redis-server ../redis_6379.conf &nohup ./redis-server ../redis_6380.conf &nohup ./redis-server ../redis_6381.conf &
(5)我们通过log来看一下主从复制过程
这份是主节点的log
这份是其中一个从节点的log
从主从的log中也可以清晰的看到主从复制的流程,其中从节点我们配置文件中设置了slave-serve-stale-data yes,这样从节点就会非阻塞的方式加载rdb文件,并且使用旧数据响应客户端读请求。
(三)登录客户端查看主从信息
使用如下命令依次登录主从节点
./redis-cli -h 127.0.0.1 -p 6379./redis-cli -h 127.0.0.1 -p 6381
使用info命令看到主从的信息:
主节点主从复制信息如下图,可以看到主节点中有两个从节点,并且从节点都在线
从节点主从复制信息,记录了主节点的相关信息
(四)使用telnet 查看Redis主节点以Redis命令协议形式发送缓存写命令
这里提供一个连接Redis服务端的Jedis工具类给大家
/** * 连接redis服务的工具类 * @author yujie.wang3 * @since 09/08/2017 */public final class RedisUtil { //Redis服务器IP private static String ADDR = "10.4.36.87"; //Redis的端口号 private static int PORT = 6379; //可用连接实例的最大数目,默认值为8; //如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。 private static int MAX_ACTIVE = 100; //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。 private static int MAX_IDLE = 20; //等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException; private static int MAX_WAIT = 10000; private static int TIMEOUT = 10000; //在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的; private static boolean TEST_ON_BORROW = true; private static JedisPool jedisPool = null; /** * 初始化Redis连接池 */ static { try { JedisPoolConfig config = new JedisPoolConfig(); config.setMaxActive(MAX_ACTIVE); config.setMaxIdle(MAX_IDLE); config.setMaxWait(MAX_WAIT); config.setTestOnBorrow(TEST_ON_BORROW); jedisPool = new JedisPool(config, ADDR, PORT); } catch (Exception e) { e.printStackTrace(); } } /** * 获取Jedis实例 * @return */ public synchronized static Jedis getJedis() { try { if (jedisPool != null) { Jedis resource = jedisPool.getResource(); return resource; } else { return null; } } catch (Exception e) { e.printStackTrace(); return null; } } /** * 释放jedis资源 * @param jedis */ public static void returnResource(final Jedis jedis) { if (jedis != null) { jedisPool.returnResource(jedis); } }}
我们使用如下代码写入和读取key
/** * 测试Redis主节点以Redis命令协议的形式向从节点发送写命令 * @author yujie.wang * @since 09/08/2017 */public class RedisTest {public static void main(String[] args) {String key0 = "yujie_";String value = "";for(int i = 0; i <= 10000; i++){String key = key0 + String.valueOf(i);value = String.valueOf(i);//写入keyaddKeys(key, value);System.out.println("add key"+ key + " value: "+ value);try {Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}//读取keySystem.out.println("get_Key: " + key + " : "+ getKey(key));}}public static String getKey(String key) {Jedis client = RedisUtil.getJedis();String value = client.get(key);RedisUtil.returnResource(client);return value;}public static void addKeys(String key ,String value){Jedis client = RedisUtil.getJedis();client.set(key, value);RedisUtil.returnResource(client);}}
启动程序之后我们使用telnet 127.0.0.1 6379 访问主节点,并发送sync命令:
从这个过程可以看到 主节点首先传过来一个包含内存中数据的rdb文件,之后会以redis命令协议的形式发送写命令,并且每写一个命令就会发送一个命令。基于此我们可以实现redis的读写分离机制。
- 详细讲解Redis主从结构配置以及复制原理(一)
- 详细讲解Redis主从结构配置以及复制原理(二)
- MySQL 主从复制 详细讲解(一)
- redis单机配置主从复制星形结构
- Redis 讲解系列之 Redis的主从复制(一)
- Redis主从复制原理
- redis主从复制原理
- redis主从复制原理
- Redis主从复制配置
- redis主从复制配置
- redis主从复制配置
- redis配置主从复制
- Redis主从复制配置
- redis配置主从复制
- Redis主从复制配置
- redis 主从复制配置
- redis配置主从复制
- redis 主从配置/复制
- Catalogue/update in 2017.12.07
- 构建自定义的同步工具
- jedis在项目中的应用
- 2LIS_06_INV的初始化
- Kubernetes(k8s)如何使用kube-dns实现服务发现
- 详细讲解Redis主从结构配置以及复制原理(一)
- 注意SSL证书和中级证书的证书链匹配
- 【算法题】判断素数/质数
- 实习项目记录
- 通过IP访问MYsql
- 如何玩转网络安全下的深度学习?最全的学习资料清单看这里
- Leetcode c语言-Add Two Numbers
- ESP8266连接Yeelink云平台实现远程控制
- 【binary-tree-level-order-traversal-ii】