本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2022-07-07
总体步骤:
示例安装tomcat:
# 拉取镜像
docker pull tomcat
# 查看镜像
docker images tomcat
# 启动镜像
docker run -it -p 8080:8080 --name=mytomcat tomcat
# 新版tomcat默认页面不存在webapps中,要登录进去删掉将webapps.dist复制为webapps
# /usr/local/tomcat
rm -r webapps
mv webapps.dist webapps
示例安装mysql:
# 查找镜像
docker search mysql
# 拉取指定版本
docker pull mysql:5.7
# 运行mysql容器 可以先查看容器有没有mysql=> ps -ef | grep mysql
# 数据库要指定容器卷避免删除容器数据丢失
docker run -p 3306:3306 --privileged=true
-v /xxx/mysql/log:/var/log/mysql
-v /xxx/mysql/data:/var/lib/mysql
-v /xxx/mysql/conf:/etc/mysql/conf.d
-e MYSQL_ROOT_PASSWORD=your-password
--name=some-mysql
-d mysql:5.7
# 查找到启动的mysql容器id
docker ps
# 进入容器,打开命令行
docker exec -it 容器id bash
# 连接mysql
mysql -u root -p
# 输入密码 进入mysql
show databases;
# 需要修复mysql的默认字符集
# 先查看
show variables like 'character%';
# 宿主机 /xxx/mysql/conf 目录下新建mysql配置文件 以解决中文乱码问题
cd /xxx/mysql/conf
vim my.cnf
# 编辑以下内容
[client]
default_character_set=utf8
[mysqld]
collation_server=utf8_general_ci
character_set_server=utf8
# 重启容器
docker restart some-mysql
示例简单安装redis:
# 直接run就会去拉取
docker run -d -p 6379:6379 --privileged=true redis:6.0.8
# 查看容器并使用exec进入
docker exec -it 容器id bash
# 进入容器
# 连接redis
redis-cli
# 插入数据
set k1 v1;
日常应用redis:
# 在宿主机上建立目录
mkdir -p /app/redis
cd /app/redis
# 找一份默认的redis.conf拷贝过来 http://download.redis.io/redis-stable/redis.conf
vim redis.conf
# 并修改以下选项
# 1、允许redis外地连接 注释掉 bind=127.0.0.1
# 2、将daemonize yes注释或者daemonize no,因为该配置和docker run中的-d参数会冲突
# 3、requirepass 注释掉,免除输密码 可选操作
# 4、开启redis数据持久化 appendonly yes 可选操作
docker run -d -p 6379:6379 --name myredis
--privileged=true
-v /app/redis/redis.conf:/etc/redis/redis.conf
-v /app/redis/data:/data/redis/data
-d redis:6.0.8 redis-server /etc/redis/redis.conf
# redis-server /etc/redis/redis.conf
# 让redis根据我们同步的redis.conf去启动
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=yourpassword \
-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
# 输入密码
5、master容器实例内创建数据同步用户
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=yourpassword \
-d mysql:5.7
7、进入 /mydata/mysql-slave/conf 目录新建 my.cnf
[mysqld]
# 设置server_id 同一局域网中需要唯一
server_id=102
# 指定不需要同步的数据可以名称
binlog-ignore-db=mysql
# 开启二进制日志功能
log-bin=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=mall-mysql-relay-bin
# 表示slave将复制时间写进自己的二进制日志
log_slave_updates=1
# slave 设置为只读 具有super权限的用户除外
read_only=1
8、修改完配置后重启slave实例
docker restart mysql-slave
9、在主数据库中查看主从同步状态
show master status;
10、进入mysql-slave容器
docker exec -it mysql-slave /bin/bash
mysql -u root -p
# 输入密码
11、在从数据库中配置主从复制
# 进入mysql命令行
# 下面两个的值是在第9步中可以查看
# master_log: mall-mysql-bin.000001 指定从数据库要复制数据的日志文件
# master_log_pos: 617 指定从数据库从哪个位置开始复制数据
change master master_host='主数据库ip(在这即宿主机ip)',master_user='slave',master_password='123456',master_root=3007,master_log='mall-mysql-bin.000001',master_log_pos=617,master_connect_retry=30;
12、在从数据库中查看主从同步状态
# \G是竖着的键值对展示数据
show slave status \G;
# 主要查看 Slave_IO_Runing 和 Slave_SQL_Running
13、在从数据库开启主从同步
start slave;
14、查看从数据库状态检查是否同步
# Slave_IO_Runing 和 Slave_SQL_Running 变成yes
show slave status \G;
15、主从复制测试
在主数据库建库建表插数据,在从数据库查看是否同步到。
先要ping同对应服务器
ping xx.xxx.xxx.xxx
telnet xx.xxx.xxx.xxx 3306
如果端口不同需要开防火墙,或者检查云服务器的防火墙是否开通了3306端口
腾讯云 https://console.cloud.tencent.com/lighthouse/instance/detail?rid=1&id=lhins-azqkbqz1&tab=firewall
sudo systemctl stop firewalld #关闭防火墙
sudo systemctl disable firewalld #重启后也不开启防火墙
# 单独打开3306端口
sudo firewall-cmd --zone=public --permanent --add-port=3306/tcp
sudo firewall-cmd --reload #永久开启3306端口
查看MySQL的信息
select host,user,plugin,authentication_string from mysql.user;
-- host为 % 表示不限制ip localhost表示本机使用
-- plugin非mysql_native_password 则需要修改密码
alter user 'root'@'%' identified with mysql_native_password by 'yourpass';
flush privileges;
或者直接新建用户
USE mysql;
CREATE USER 'user'@'%' IDENTIFIED BY 'yourpass';
GRANT ALL ON *.* TO 'user'@'%';
FLUSH PRIVILEGES;
1、哈希取模算法:根据redis机器的数量n,每次使用key算出来的hash值进取模n,进行分布式存储。缺点是不好扩展,每次扩展n都会发生变化。
2、一致性哈希算法:将0~2^32-1组成一个环形,将redis节点分布在环上,每次使用key算出来的hash值对2^32-1取模,然后以顺时针方向找到最近的redis节点进行存储。缺点是可能出现数据倾斜(分布不均匀导致分配不均匀)问题,例如两个节点且挨得很近,顺时针方向寻找下就会出现。
3、哈希槽算法:在数据和节点之间又加入了一层,称之为哈希槽,用于管理数据和节点之间的关系,现在就相当于节点上放槽,槽里放数据。建立一个有0~16383(2^14-1)个槽,将这16384个槽分配个多台reids机器。解决的是粒度问题,相当于把粒度变大了,便于数据移动。槽的叔母是固定的。
1、新建6个redis容器,3主3从
# --net host 使用宿主机的ip和端口
# --privileged=true 获取宿主机的root权限
# --cluster-enabled 开启redis集群
# --appendonly 开启持久化
# --port redis端口
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 yse --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 yse --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 yse --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 yse --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 yse --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 yse --appendonly yes --port 6386
2、建立主从关系
# 进入容器实例redis-node-1
# 宿主机ip
redis-cli --cluster create yourip:6381 yourip:6382 yourip:6383 yourip:6384 yourip:6385 yourip:6386 --cluster-replicas 1
# --cluster-replicas 1 指为每个master创建一个slave节点
# 输入yes
# 打印信息中M: 标识的是主,S:表示的从
3、查看集群状态
# 在redis-node-1 这个容器下
redis-cli -p 6381
# 进入redis命令行交互
# 查看集群信息 并能看到master机器的哈希槽的范围
cluster info
# 能发现主从对应关系
cluster nodes
# master 一行中的 1 2 3 与 slave每行中的1 2 3 一一对应
# 也可以看id
# id ip slave masterid
# id ip master slaveid
1、主从容错切换迁移案例
数据存储的问题:
# 在redis-node-1 这个容器下
redis-cli -p 6381
# 进入redis命令行交互
# 进行set命令时,如果key的hash值超过了 哈希槽分配的节点值访问将会报错
# hash值超过了分配的哈希槽 需要move到对应的另一台机 但是此时使用的是-p直接进入的redis单机模式 所以移动失败
# (error) MOVED 12706 yourip:638x
# 可以使用-c进入集群模式
redis-cli -p 6381 -c
# 当set时,key的hash值超过当前连接的机器的哈希槽范围 会自动重定位到应该去的哈希槽的那台机器中
# 并且此时redis-cli会自动切换到那一台机的交互命令终端下
# 检查某一台机器的集群状况
redis-cli --cluster check 127.0.0.1:6381
演示主机宕机,从机能不能上位备用
# 停止一台主机 redis-node-1
docker stop redis-node-1
# 进入2号机
docker exec -it redis-node-2 bash
# 以2号机进入集群
redis-cli -p 6382 -c
cluster nodes
# 可以查询到1号master已经fail了 现在1号之前的slave那台机 就从slave变成了master
# 如果此时 redis-node-1 重新启动了
# 退出到宿主机
docker start redis-node-1
# 此时回来的redis-node-1就变成了slave
# 如果想恢复,可以先停掉已经上位的从机,在等一会重新启动(可使用cluster nodes查看redis-node-1是否恢复成了master) 主从关系就恢复了
2、主从扩容案例
# 新增并启动两台redis容器实例
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 yse --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 yse --appendonly yes --port 6388
# 将新增的 6387 节点作为master结点加入原集群
docker exec -it redis-node-7 /bin/bash
redis-cli --cluster add-node yourip:6387 yourip:6381
# 检查集群状态
redis-cli --cluster check yourip:6381
# 可以看到6387变成了第4台master主机 但是此时还没有槽位
# 重新分配槽位
redis-cli --cluster reshard yourip:6381
# 会问你要分配多少个槽位 需要注意的是 这里是重新分配
# 输入4096 (16384 / 4)
# 会问你让哪一个机器来接收
# 将6387的node id 输入
# 会问你从谁那里获取这些槽位
# 会问你 all 还是 done,all代表从当前全部的redis主机那里分别拿出来一些来凑出4096个分给新的
# 不选择all呢,就输入指定的nodeid,可以输入一个或多个,以done结束,即代表从这些输入了nodeid机器中凑出4096个分给新的
# 输入 all
# 再输入 yes
# 再次检查集群状态
redis-cli --cluster check yourip:6381
# 会发现前面的3台master主机,都将前面一点的槽位分配给了6387新加入的机器 共同构成了4096个槽位
# 为有了槽位的master主机6387 分配从机 6388
redis-cli --cluster add-node yourip:6388 yourip:6387 --cluster-slave --cluster-master-id 6387的nodeid
# 再次查看集群状态看看是不是4主4从
3、主从缩容案例
实现: 将案例中的6387、6388在集群中删掉
步骤:
(1)先删从机6388 (2)重新分配主机6387的槽号 (3)再删主机6387 (4)恢复成3主3从
# 检查集群状态 获取到6388的node id
redis-cli --cluster check yourip:6381
# yourip后面的端口任意一台机的都可以,不一定非得是6381这台机 指的是以某一台机为落脚点进行集群操作而已
# redis-cli 是在redis容器实例中执行
# 删除从机6388
redis-cli --cluster del-node yourip:6388 6388的nodeid
# 检查集群状态 查看是否被删除了
redis-cli --cluster check yourip:6381
# 重新分配槽号
redis-cli --cluster reshard yourip:6381
# 会问你要分配多少个槽位
# 输入4096 即将删除的6387就是拥有4096个槽好
# 会问你让哪一个机器来接收
# 此时将6381的node id 输入,即让6381来接收4096个槽号
# 会问你从谁那里获取这些槽位
# 这一次输入我们要删除的6387的nodeid
# 输入 6387的nodeid
# 输入 done
# 再输入 yes
# 再次检查集群状态
redis-cli --cluster check yourip:6381
# 此时6387主机的槽位就空了为 0 slots
# 6381主机为8192 slots
# 删除主机6387
redis-cli --cluster del-node yourip:6387 6387的nodeid