安装mysql的主从复制:
1、新建主服务器实例3307
docker run -p 3307:3306 --name mysql-master \
-v /mydata/mysql-master/log:/var/log/mysql \
-v /mydata/mysql-master/data:/var/lib/mysql \
-v /mydata/mysql-master/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
2、进入/mydata/mysql-master/conf目录下新建my.cnf
[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id=101
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能
log-bin=mall-mysql-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
3、修改完配置后重启master实例
docker restart mysql-master
4、进入mysql-master容器
docker exec -it mysql-master /bin/bash
mysql -u root -p
// password设置的也是root
5、master容器实例内创建数据同步用户(登录mysql执行)
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
6、新建从服务器容器实例3308
docker run -p 3308:3306 --name mysql-slave \
-v /mydata/mysql-slave/log:/var/log/mysql \
-v /mydata/mysql-slave/data:/var/lib/mysql \
-v /mydata/mysql-slave/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
7、进入/mydata/mysql-slave/conf目录下新建my.cnf
[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id=102
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能,以备Slave作为其它数据库实例的Master时使用
log-bin=mall-mysql-slave1-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
## relay_log配置中继日志
relay_log=mall-mysql-relay-bin
## log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1
## slave设置为只读(具有super权限的用户除外)
read_only=1
8、修改完配置后重启salve实例
docker restart mysql-slave
9、在主数据库中查看主从同步状态:show master status;
10、进入mysql-slave容器
docker exec -it mysql-slave /bin/bash
mysql -u root -p
// 密码设置的root
11、在从数据库中配置主从复制
change master to master_host='116.62.71.39', master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-bin.000001', master_log_pos=617, master_connect_retry=30;
配置参数解释:
12、在从数据中开启主从同步
13、在从数据库中查看主从状态
show slave status \G;
14、主从同步测试,主机插入数据,从机查看数据!!!!
安装redis集群(分布式存储案例):cluster集群模式-docker版哈希槽分区进行亿级数据存储
面试题:1~2亿条数据需要缓存,请问如何设计这个存储案例:
回答:单机单台100%不可能,肯定是分布式存储,用redis如何落地?
上述问题阿里p6~p7工程案例和场景设计必考题目,一般业界有3种解决方案:
第一种:哈希取余分区
第二种:一致性哈希算法分区
一致性Hash算法背景
一致性哈希算法在1997年由麻省理工学院中提出的,设计目标是为了解决
分布式缓存数据变动和映射问题,某个机器宕机了,分母数量改变了,自然取余数不OK了。
能干嘛:提出一致性哈希算法解决方案目的是当服务器个数发生变动时,尽量减少影响客户端到服务器的映射关系。
三大步骤:
第一步:算法构建一致性哈希环
第二步:服务器ip节点映射
第三步:key落到服务器的落键规则
一致性hash优点:
1、容错性
2、扩展性
缺点:数据倾斜问题
总结:
第三种:哈希槽分区
哈希槽计算:
redis集群三主三从-docker配置案例
1、关闭防火墙,启动docker:systemctl start docker
2、新建六个docker容器实例
docker run -d --name redis-node-1 --net host --privileged=true -v /data/redis/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381
docker run -d --name redis-node-2 --net host --privileged=true -v /data/redis/share/redis-node-2:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382
docker run -d --name redis-node-3 --net host --privileged=true -v /data/redis/share/redis-node-3:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383
docker run -d --name redis-node-4 --net host --privileged=true -v /data/redis/share/redis-node-4:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384
docker run -d --name redis-node-5 --net host --privileged=true -v /data/redis/share/redis-node-5:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385
docker run -d --name redis-node-6 --net host --privileged=true -v /data/redis/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386
如果都启动成功了效果如下所示:
3、进入容器redis-node-1并为6台机器构建集群关系
进入容器:docker exec -it redis-node-1 /bin/bash
构建主从关系(注意,进入docker容器后才能执行一下命令,且注意自己的真实IP地址):
redis-cli --cluster create 116.62.71.39:6381 116.62.71.39:6382 116.62.71.39:6383 116.62.71.39:6384 116.62.71.39:6385 116.62.71.39:6386 --cluster-replicas 1
解释:--cluster-replicas 1 表示为每个master创建一个slave节点
主从分配成功!!!!!!三主三从搞定
如果出现下图的Waiting for the cluster to join的情况,那可以参考下面贴出来的解决方法
4、链接进入6381作为切入点,查看集群状态
docker exec -it redis-node-1 /bin/bash
redis-cli -p 6381
cluster info
cluster nodes
可以看出来6381-->6385(slave),6382-->6386,6383-->6384
基于集群的主从容错切换迁移案例:
1、数据读写存储:
进入6381进行set key1 v1操作,会发现报了一个错,显示MOVED 6382,但是set k2 v2就可以,
这是因为key1经过计算槽位属于9189,而9189槽位属于6382的范围,所以连接单击6381存储就会失败。
因为我们现在是集群模式,所以应该集群模式连接客户端,这样就不会出现上面问题,
集群连接客户端:docker exec -it redis-node-1 /bin/bash
redis-cli -p 6381 -c
这个时候再set key1 v1就可以发现将客户端重定向到6382存储成功了
查看集群信息命令:redis-cli --cluster check 116.62.71.39:6381
可以看到集群相关的一切信息,如下图所示:
2、容错切换迁移:
演示:6381主机宕机,6385从机上位
步骤一:主机和从机切换,先停止主机6381
docker stop redis-node-1
停止之后我通过6382进入查看集群状态
docker exec -it redis-node-2 /bin/bash
redis-cli -p 6382 -c
cluster nodes
可以看到6385从机已经切换为主机,上位成功
那接下来如果再启动6381,那6381和6385的主从关系会有变化吗?
启动6381:docker start redis-node-1
查看集群状态:发现就算6381回来了也只能做小弟slave了
主从扩容案例:
随着业务量的增加,三主三从可能服务器压力太大了,这个时候要在原来的基础上搭建四主四从的环境,即新增6387服务器作为master,6388服务器作为slave加入到集群中。
目前三主三从回复原来状态,6381、6382、6382为master
step1:阿里云开放6387、6388、16387、16388端口,然后新建6387、6388两个节点 + 新建后启动 + 查看是否一共八个节点
docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/share/redis-node-7:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6387
docker run -d --name redis-node-8 --net host --privileged=true -v /data/redis/share/redis-node-8:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6388
docker ps
step2:进入6387容器实例内部
docker exec -it redis-node-7 /bin/bash
step3:将新增的6387节点(空槽号)作为master节点加入原集群
redis-cli --cluster add-node 自己实际IP地址:6387 自己实际IP地址:6381
// redis-cli --cluster add-node 116.62.71.39:6387 116.62.71.39:6381
解释:
6387 就是将要作为master新增节点 6381 就是原来集群节点里面的领路人,相当于6387拜拜6381的码头从而找到组织加入集群 |
6387添加节点成功!!!!!!
step4:检查集群状况第一次
redis-cli --cluster check 真实ip地址:6381 // redis-cli --cluster check 116.62.71.39:6381 |
可以看到已经变成了四个master节点
但是6387还没分配槽位
step5:重新分配槽位
重新分派槽号 命令:redis-cli --cluster reshard IP地址:端口号 redis-cli --cluster reshard 116.62.71.39:6381 |
step6:检查集群情况第二次
redis-cli --cluster check 真实ip地址:6381 // redis-cli --cluster check 116.62.71.39:6381 |
可以看到6387的4096个槽位是其他三家每一家都匀出来一些给凑成的。
为什么会这样呢?
重新分配成本太高,所以前3家各自匀出来一部分,从6381/6382/6383三个旧节点分别匀出 1364个坑位给新节点6387 |
step7:为主节点6387分配从节点6388
命令:redis-cli --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id 新主机master节点ID(即6387的)
redis-cli --cluster add-node 116.62.71.39:6388 116.62.71.39:6387 --cluster-slave --cluster-master-id 41cc8f028ca62d30868a977a2476cd527a95e2f7
从机挂载到6387下面,成功!!!!!!
step8:检查集群情况第三次
redis-cli --cluster check 116.62.71.39:6382 |
主从缩容案例:
流量高峰过去了,四主四从有点浪费资源了,redis集群缩容,删除6387和6388,恢复三主三从
step1:检查集群情况,获得6388从节点的ID
redis-cli --cluster check 116.62.71.39:6382
|
step2:从集群中将6388删除
命令:redis-cli --cluster del-node ip:从机端口 从机6388节点ID
###redis-cli --cluster del-node 116.62.71.39:6388 2a8ca51812e8203cfb8c95d29da9a6079c40d7df
redis-cli --cluster check 116.62.71.39:6382 检查一下集群情况,可以看到6388已删除
step3:将6387的槽号清空,重新分配,本例将清出来的槽号都给6381
redis-cli --cluster reshard 116.62.71.39:6381
step4:检查集群情况第二次,可以看到6387槽位0,6381槽位4096*2个
redis-cli --cluster check 116.62.71.39:6382
|
step5:将6387节点从集群中删除
命令:redis-cli --cluster del-node ip:端口 6387节点ID
redis-cli --cluster del-node 116.62.71.39:6387 41cc8f028ca62d30868a977a2476cd527a95e2f7
step6:检查集群情况第三次,可以看到6387节点已经没有了
redis-cli --cluster check 116.62.71.39:6382
|
集群案例完结,撒花!!!!!!