目标
1.对数据库底层的压力知道如何去提供解决方案和思路
2.对分库分表的常用手段
3.了解Mysql的主从及binlog
4.知道Mycat及其他相似的中间件
为什么要分库分表
1.数据的超大容量问题
2.磁盘IO性能问题
如何去做到
垂直切分
水平切分
1.垂直分库:按功能模块进行拆分,用户数据库、账单数据库、交易数据库;解决表过多的问题。
2.垂直分表:解决单表列过多的问题。大表字段多,性能瓶颈问题。
3.水平切分:大数据表拆分小表,单表性能500万到1000万性能比较好。(将一亿条记录的表拆分成10张1000万的小表)
常见的拆分策略
1.垂直拆分(领域模型 er分片)
2.水平拆分
一致性hash
范围切分 可以按照ID
日期拆分
拆分后带来的问题
1.跨库join的问题;select a库.x,b库.y from a join b on a.id=b.id
解决办法:
1.提供接口,使用接口查询,先调用A系统,再调用B系统(RPC)
for(list){
rpcsevice.select(id);//避免这样循环调用rpc
}
2.做全局表 公共数据,公共服务
数据变更比较少的基于全局应用的表
3.适当做字段冗余(空间换时间)
订单表[商家名称]、商家表
商家名称变更:定时任务、任务通知
2.跨分片数据排页
解决办法:
应用层去做拼接,每个表做一次查询,排序。
3.唯一主键问题
用自增id做主键,id在不同库中会出现重复。
UUID 性能比较低,索引比较大
snowflake 雪花算法:时间序列+机器标识+计数顺序号
zookeeper 自增id
redis
数据库表
4.分布式事务
多个数据库表之间保证原子性
2pc,3pc,强一致性带来的性能问题
物联网公司用强一致性分布式事务比较少
5.分库分表最难的在于业务的复杂度
如何权衡当前公司的存储需要优化
1.提前规划(主键问题解决、join问题)
2.当前数据单表超过1000万、每天的增长量持续上升
Mysql主从配置
Mysql5.7安装
下载rpm包
wget https://repo.mysql.com//mysql57-community-release-el7-11.noarch.rpm
安装rpm包
rpm -ivh mysql57-community-release-el7-11.noarch.rpm
安装mysql
yum install mysql-server
启动mysql服务
systemctl start mysqld
查看默认密码
grep “password” /var/log/mysqld.log
启动mysql
mysql -uroot -p 并且数据上面返回的默认密码
可选:修改安全策略 使用简易密码
set global validate_password_length=1;
set global validate_password_policy=0;
mysql> set password=password(“root”);
设置如何服务器可以访问我这台mysql
GRANT ALL PRIVILEGES ON . TO ‘root’@’%’ IDENTIFIED BY ‘root’ WITH GRANT OPTION;
查看是否安装成功
主从配置
创建一个用户 用来数据同步
create user hefan identified by ‘hefan’;
给用户赋权
grant replication slave on . to ‘hefan’@’%’ identified by ‘hefan’;
修改etc/my.cnf文件
mysql的数据文件和二进制文件:/var/lib/mysql/
mysql的配置文件:/etc/my.conf
mysql的日志文件:/var/log/mysql.log
[mysqld]
#开启mysql二进制日志文件
log-bin=mysql-bin
server-id=唯一id
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
查看master二进制文件和position
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql>
修改slave数据库my.cnf文件
[mysqld]
server-id=2
relay-log=slave-relay-bin
relay-log-index=slave-relay-bin.index
read_only=1
配置slave连接master
change master to master_host=’192.168.0.100’,master_port=3306,master_user=’hefan’,master_password=’hefan’,master_log_file
=’mysql-bin.000001’,master_log_pos=154;
启动服务
start slave;
查看是否配置成功
show slave status\G;
主从同步原理
binlog:用来记录mysql的数据更新或者潜在更新
文件内容存储:/var/lib/mysql/mysql-bin.000001
查看:mysqlbinlog —base64-output=decode-rows -v mysql-bin.000001
binlog的格式
statement:基于sql语句的模式,update table set name=””; effect row 1000; uuid、now() other function
row:基于行模式;存在1000条数据变更;记录修改以后每一条记录变化的值;
mixed:混合模式,由mysql 自动判断处理;
修改 binlog_formater:set global binlog_format=row/mixed/statement;
或者在 my.cnf中添加 binlog_format=row;
主从同步带来的延迟问题
binlog_cache缓存(性能和数据安全权衡)
sync_binlog=0 文件系统来调度binlog_cache刷新到磁盘
sync_binlog=n
延迟监控
Nagios 做网络监控
mk-heartbeat
应用层的解决方案 redis
主从同步存在网络延迟,可以先将数据写入redis,当缓存失效的时候,才从数据库取,时间差过度。
了解binlog及主从复制原理
网络配置
Cannot find a valid baseurl for repo: base/7/x86_64
Cannot find a valid baseurl for repo: base/7/x86_64
[root@localhost local]# ping www.baidu.com
ping: www.baidu.com: 未知的名称或服务
[root@localhost local]# ping www.baidu.com
ping: www.baidu.com: 未知的名称或服务
[root@localhost local]# cd /etc/sysconfig/network-scripts
[root@localhost network-scripts]# ls
ifcfg-enp0s3 ifdown-bnep ifdown-isdn ifdown-sit ifup ifup-ippp ifup-plusb ifup-sit ifup-wireless
ifcfg-enp0s8 ifdown-eth ifdown-post ifdown-Team ifup-aliases ifup-ipv6 ifup-post ifup-Team init.ipv6-global
ifcfg-lo ifdown-ippp ifdown-ppp ifdown-TeamPort ifup-bnep ifup-isdn ifup-ppp ifup-TeamPort network-functions
ifdown ifdown-ipv6 ifdown-routes ifdown-tunnel ifup-eth ifup-plip ifup-routes ifup-tunnel network-functions-ipv6
[root@localhost network-scripts]# vi ifcfg-enp0s3
[root@localhost network-scripts]# service network restart
Restarting network (via systemctl): [ 确定 ]
[root@localhost network-scripts]#
[root@localhost network-scripts]#
[root@localhost network-scripts]# ping www.baidu.com
PING www.wshifen.com (119.63.197.151) 56(84) bytes of data.
64 bytes from 119.63.197.151 (119.63.197.151): icmp_seq=1 ttl=46 time=267 ms
64 bytes from 119.63.197.151 (119.63.197.151): icmp_seq=2 ttl=46 time=263 ms
64 bytes from 119.63.197.151 (119.63.197.151): icmp_seq=3 ttl=46 time=248 ms
^C
--- www.wshifen.com ping statistics ---
4 packets transmitted, 3 received, 25% packet loss, time 3007ms
rtt min/avg/max/mdev = 248.027/259.552/267.205/8.294 ms
[root@localhost network-scripts]#
安装wget
yum -y install wget