目标

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;

查看是否安装成功

show databases;

主从配置

创建一个用户 用来数据同步

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

  1. [mysqld]
  2. #开启mysql二进制日志文件
  3. log-bin=mysql-bin
  4. server-id=唯一id
  5. # join_buffer_size = 128M
  6. # sort_buffer_size = 2M
  7. # read_rnd_buffer_size = 2M
  8. datadir=/var/lib/mysql
  9. socket=/var/lib/mysql/mysql.sock
  10. # Disabling symbolic-links is recommended to prevent assorted security risks
  11. symbolic-links=0
  12. log-error=/var/log/mysqld.log
  13. pid-file=/var/run/mysqld/mysqld.pid

查看master二进制文件和position

  1. mysql> show master status;
  2. +------------------+----------+--------------+------------------+-------------------+
  3. | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
  4. +------------------+----------+--------------+------------------+-------------------+
  5. | mysql-bin.000001 | 154 | | | |
  6. +------------------+----------+--------------+------------------+-------------------+
  7. 1 row in set (0.00 sec)
  8. mysql>

修改slave数据库my.cnf文件

  1. [mysqld]
  2. server-id=2
  3. relay-log=slave-relay-bin
  4. relay-log-index=slave-relay-bin.index
  5. 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;
image.png

主从同步原理

image.png

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

  1. Cannot find a valid baseurl for repo: base/7/x86_64
  2. [root@localhost local]# ping www.baidu.com
  3. ping: www.baidu.com: 未知的名称或服务
  4. [root@localhost local]# ping www.baidu.com
  5. ping: www.baidu.com: 未知的名称或服务
  6. [root@localhost local]# cd /etc/sysconfig/network-scripts
  7. [root@localhost network-scripts]# ls
  8. ifcfg-enp0s3 ifdown-bnep ifdown-isdn ifdown-sit ifup ifup-ippp ifup-plusb ifup-sit ifup-wireless
  9. ifcfg-enp0s8 ifdown-eth ifdown-post ifdown-Team ifup-aliases ifup-ipv6 ifup-post ifup-Team init.ipv6-global
  10. ifcfg-lo ifdown-ippp ifdown-ppp ifdown-TeamPort ifup-bnep ifup-isdn ifup-ppp ifup-TeamPort network-functions
  11. ifdown ifdown-ipv6 ifdown-routes ifdown-tunnel ifup-eth ifup-plip ifup-routes ifup-tunnel network-functions-ipv6
  12. [root@localhost network-scripts]# vi ifcfg-enp0s3
  13. [root@localhost network-scripts]# service network restart
  14. Restarting network (via systemctl): [ 确定 ]
  15. [root@localhost network-scripts]#
  16. [root@localhost network-scripts]#
  17. [root@localhost network-scripts]# ping www.baidu.com
  18. PING www.wshifen.com (119.63.197.151) 56(84) bytes of data.
  19. 64 bytes from 119.63.197.151 (119.63.197.151): icmp_seq=1 ttl=46 time=267 ms
  20. 64 bytes from 119.63.197.151 (119.63.197.151): icmp_seq=2 ttl=46 time=263 ms
  21. 64 bytes from 119.63.197.151 (119.63.197.151): icmp_seq=3 ttl=46 time=248 ms
  22. ^C
  23. --- www.wshifen.com ping statistics ---
  24. 4 packets transmitted, 3 received, 25% packet loss, time 3007ms
  25. rtt min/avg/max/mdev = 248.027/259.552/267.205/8.294 ms
  26. [root@localhost network-scripts]#

安装wget

  1. yum -y install wget