主从的好处
通过主从扩展 主负责写 从负责读,来实现高负载。
设置主服务器
优点:不用重启服务器 确点不方便管理,下次重启需要重新制定
通过命令
Connected. 本地6380:0>slaveof 127.0.0.1 6379 OK
通过配置文件
// 配置文件中配置 slaveof ip port slave-read-only yes //只允许从节点进行读操作
主从复制原理
1.连接主服务,并发送sync命令
2.主服务器接受到命令,执行bgsave生成快照,并在缓冲区保存bgsave之后的所有写命令
3.从服务器在主服务器未收到主服务器快照文件推送,如果接收到读请求,根据配置文件区分是使用现有库数据还是直接返回异常
4.主服务器bgsave执行完毕向从服务器发送快照文件并在发送期间继续使用缓冲区记录被执行的写命令
5.从服务器接收到快照文件,则丢弃本地所有数据,执行快照的载入
6.快照文件发送完毕,则发送缓冲区的所有写命令,后续每执行一条写命令,都像从服务器发送一条相同的写命令
7.从服务器快照加载完毕,可以像往常正常接收读请求
8.接收并执行主服务器推送的缓冲器写命令请求,并且从现在开始接收主服务器传来的每个写命令
redis主从链
redis不支持多主主复制 当一台从服务器并不能满足读的请求的时候可以设置多个读服务器
确保写入同步到了磁盘和从服务器
以下有很多不严谨的地方,只是一种参考思路
public static void main(String[] args) throws Exception { Jedis master = new Jedis("127.0.0.1", 6379); Jedis slave = new Jedis("127.0.0.1", 6380); addProductName(master,slave,"user:1","小明"); }
/** * * @param mconn 主服务器 * @param sconn 从服务器 * @param id * @param name * @throws InterruptedException */ public static void addProductName(Jedis mconn, Jedis sconn, String id, String name) throws InterruptedException { //加入主服务器 mconn.hset(id,"name",name); //感觉可以不要 判断主从状态是否正常 如果未和主连接则是down while (!sconn.info("master_link_status").equals("up")){ //等待1毫秒 Thread.sleep(1); } /** * 确保从服务器已经同步到了最新数据 */ while (sconn.hget(id,"name")!=null&&sconn.hget(id,"name").equals("name")){ break; } //因为默认配的一秒刷盘一次 最多等待一秒 Long waitTime=System.currentTimeMillis()+1000; while (System.currentTimeMillis()<waitTime){ /** * 当磁盘压力过大aof文件写入可能会阻塞,每次阻塞 info里面aof_pending_bio_fsync 会累加 写入后清零 * 确保aof写入到了磁盘 */ if(mconn.info("aof_pending_bio_fsync").equals("0")){ break; } } }
切换主服务器
当主服务器出现问题,短时间不能恢复时,切换主服务器的2种方式
方式1
从服务器执行save 将rdb传到新的主服务器目录,然后启动服务器, 从服务器的主服务器切换为新的主服务器
方式2
从服务器直接升级为主服务器 然后将新的从服务器设置主服务器