老鱼进阶篇-Mysql从入门到精通-下篇

333 阅读20分钟

这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战

1、性能优化分析篇

1.1 慢查询日志分析

1.1.1 慢日志查询分析

数据库查询速度比较慢是影响项目整体性能的一大关键因素,所以需要从众多的sql语句中分析出查询耗时的sql来进行针对性分析。因此需要开启数据库的“慢查询日志”功能来进行跟踪处理。

慢日志查询开启后是比较消耗数据库性能的,因此默认是关闭的,需要手动进行开启。

#查询是否开启
show variables like '%slow_query%';
#慢查询的配置阈值
show variables like 'long_query_time%';
- 【slow_query_log】 :是否开启慢查询日志,ON(1)为开启,OFF(0)为关闭。默认关闭。 
- 【slow_query_log_file】:MySQL数据库慢查询日志存储路径及文件。(可以不设置该参数, 默认和数据文件在一起,系统则会默认给一个缺省的文件host_name-slow.log),建议自定义路径和 文件名。 
- 【long_query_time】 :慢查询执行时间的阈值,当查询语句的执行时间大于设定的阈值时,记 录到日志。默认10秒,单位为秒。 
- 【log_queries_not_using_indexes】 :是否记录未使用索引的SQL。ON(1)为开启, OFF(0)为关闭。默认关闭。 
- 【log_output】 :日志输出的地方,默认File。【File】:仅写入日志文件,【Table】仅写 入日志表,【File,Table】同时写入日志表和日志文件。 日志表位置:mysql.slow_log。log_output:生产环境,建议使用默认值File。Table方式比较耗费性能。

慢查询的sql包含以下两类:

  • log_queries_not_using_indexes=0:仅记录执行时间大于long_query_time,使用了索引的查询SQL和更新SQL(包含已回滚的更新SQL)。
  • log_queries_not_using_indexes=1:记录所有执行时间大于long_query_time的查询SQL和更新SQL(包含已回滚的更新SQL)。

临时开启慢查询命令:

#例如: 
set global slow_query_log = ON; 
set global long_query_time = 1;#1秒,0不限制时间记录所有的sql 
set global slow_query_log_file = '/var/lib/mysql/slow-2020-0518.log';#建议不要 使用默认的路径和名称,建议自定义路径和文件名。 
set global log_queries_not_using_indexes = 1;#记录未使用索引的SQL 
set global log_output='FILE,Table'

永久开启慢查询命令:修改/etc/my.cnf配置文件,重启 MySQL

[mysqld] 
slow_query_log = 1 #建议不要使用默认的路径和名称,建议自定义路径和文件名。 
slow_query_log_file =/var/lib/mysql/slow.log 
long_query_time = 1

分析思路:

#查看慢查询日志有多少慢查询 
show global status like 'slow_queries'; 
#慢查询日志路径 
show VARIABLES like 'slow_query_log_file';
#返回结果关键参数分析
Query_time,执行这条SQL花费的时间,单位秒,越长则越慢。 
Lock_time,在MySQL服务器阶段(不是在存储引擎阶段)等待表锁时间 
Rows_sent:查询返回的行数 
Rows_examined:扫描的数据行数,越大当然越费时间

1.1.2 慢日志分析工具

  • mysqldumpslow:mysqldumpslow是MySQL自带的慢查询日志工具,在 MySQL 的 bin 目录下。可以使用mysqldumpslow工具搜索慢查询日志中的SQL语句:汇总除查询条件外完全相同的SQL(分组), 并将分析结果按照所指定的顺序输出。

    例如:查询耗时最多的10条sql中含有左连接的查询语句:

    [root@localhost mysql]# mysqldumpslow -s t -t 10 -g “left join” slow-log.log
    

    结果分析:

    Count: 执行了多少次 
    Time: 平均执行的时间(累计的总执行时间) 
    Lock: 等待锁的时间(累计的总时间) 
    Rows: 返回的平均记录数(累计的总记录数) 除查询条件外完全相同的SQL语句
    
  • pt-query-digestpercona-toolkit: pt-query-digest是percona-toolkit的一个工具。percona-toolkit是一组高级命令行工具的

    集合,可以查看当前服务的摘要信息,磁盘检测,分析慢查询日志,查找重复索引,实现表同步等等。

    下载路径:www.percona.com/downloads/p…

    具体使用方方法请参考官网说明,不再做详细描述。

  • 实时获取有性能问题的SQL

    #获取执行时间超过30秒的sql 
    SELECT ID,`USER`,`HOST`,DB,COMMAND,TIME,STATE,INFO FROM information_schema.`PROCESSLIST` WHERE TIME >= 30 And (INFO like 'select%' or INFO like 'insert%' or INFO like 'update%' or INFO like 'delete%')
    

    通过在服务器配置定时脚本周期性的执行以上SQL,就可以实时获取有性能问题的SQL。发现有性能问题的SQL,然后通过报警机制发送报警信息,这样可以实时监控系统的慢查询的情况。

1.2 性能分析工具

1.2.1 profile

profile是MySQL自带的一种query诊断分析工具,通过它可以分析出一条SQL语句的性能瓶颈在什么地方。

官网:dev.mysql.com/doc/refman/…

使用show profile可以定位出一条SQL语句执行使用的各种资源消耗情况,比如消耗时间, CPU,IO等,默认的情况下,通过profiling参数控制是否开启该功能。MYSQL的该功能没有打开,需要手动启动。

这个命令只是在本会话内起作用,即无法分析本会话外的语句。

#查看profile功能是否开始,profiling默认是关闭 
SELECT @@profiling;
#开启profile功能--1是开启、0是关闭 
set profiling=1;
#查询返回参数>> query_id:查询id,以1开始 Duration:花费的时间 Query:查询语句
show profiles
#根据上面的查询结果可以查询每个阶段消耗的时间n=query_id
show profile for query n;

show profile 和 show profiles 语句可以展示当前会话中执行语句的资源使用情况。

show profiles :显示最近n条当前连接中最近在服务器上执行的语句的消耗时间的情况。显示的记录数由变量:profiling_history_size 控制,默认15条。

show profile for query n:根据 show profiles 列表中的 Query_ID,展示Query_ID=n的查询语句在每个阶段的消耗时间的情况。默认显示 Status和Duration两列

1.2.2 Performance Schema

官网地址:dev.mysql.com/doc/refman/…

profile工具已经过时,建议使用 Performance Schema进行性能分析 ,这是官方推荐使用的方式。

Performance Schema是一种在较低级别在运行时监视MySQL Server服务器执行情况的功能。它是使用 PERFORMANCE_SCHEMA存储引擎和performance_schema数据库来实现的。PERFORMANCE_SCHEMA存储引擎是在MySQL 5.5引入的。MySQL 5.5开始新增一个数据库:PERFORMANCE_SCHEMA,主要用于收集数据库服务器性能参数。用户是不能创建存储引擎为PERFORMANCE_SCHEMA的表。

Performance Schema这个功能在5.5中默认没有启用,5.6及其之后的版本默认启用。通过合理的配置和使用performance_schema数据库中的表,能为我们解决一些瓶颈问题提供帮助。

  • 检查当前数据库版本是否支持

    Performance Schema库中表使用的是PERFORMANCE_SCHEMA存储引擎,它是MySQL5.5引入的一个性能分析的存储引擎。可以通过INFORMATION_SCHEMA.ENGINES表或者show engines;命令查询支持INFORMATION_SCHEMA引擎。如果该引擎可用,则对应的Support 字段输出为YES。

    show engines; 
    SELECT * FROM information_schema.`ENGINES` WHERE ENGINE ='PERFORMANCE_SCHEMA';
    
  • 启用performance_schema

    # 注意:该参数为只读参数,需要在配置文件设置,MySQL重启生效 
    show VARIABLES like 'performance_schema';
    #MySQL5.7.29 一共87张表 
    show tables from performance_schema;
    
  • 查看查询语句在每个阶段的消耗时间的情况

    #开启配置,采集阶段事件项信息,进行耗时统计。 
    mysql> use performance_schema; 
    mysql> UPDATE setup_instruments SET ENABLED = 'YES', TIMED = 'YES' where name like 'stage%'; 
    mysql> UPDATE setup_consumers SET ENABLED = 'YES' where name like 'events%';
    
    #查询当前连接所有查询语句在每个阶段的消耗时间的情况。获取有性能问题的sql
    mysql>use performance_schema; SELECT a.THREAD_ID,a.EVENT_ID, c.EVENT_NAME,a.SQL_TEXT ,(c.TIMER_END-c.TIMER_START)/1000000000 AS DURATION_ms FROM events_statements_history_long a inner JOIN threads b ON a.THREAD_ID =b.THREAD_ID inner JOIN events_stages_history_long c ON b.THREAD_ID=c.THREAD_ID AND c.EVENT_ID BETWEEN a.EVENT_ID AND a.END_EVENT_ID WHEREb.PROCESSLIST_ID=CONNECTION_ID() AND a.EVENT_NAME= 'statement/sql/select' ORDER BY a.THREAD_ID,c.EVENT_ID;
    
    #查看当前连接查询语句各个阶段耗时大于4秒的
    SELECT a.THREAD_ID,a.EVENT_ID, c.EVENT_NAME,a.SQL_TEXT ,(c.TIMER_END-c.TIMER_START)/1000000000 AS DURATION_ms FROM events_statements_history_long a inner JOIN threads b ON a.THREAD_ID =b.THREAD_ID inner JOIN events_stages_history_long c ON b.THREAD_ID=c.THREAD_ID AND c.EVENT_ID BETWEEN a.EVENT_ID AND a.END_EVENT_ID WHEREb.PROCESSLIST_ID=CONNECTION_ID() AND a.EVENT_NAME= 'statement/sql/select' and (c.TIMER_END-c.TIMER_START)/1000000000>4000 ORDER BY a.THREAD_ID,c.EVENT_ID;
    
    # 查看所有连接查询语句各个阶段耗时大于4秒的
    SELECT a.THREAD_ID,a.EVENT_ID, c.EVENT_NAME,a.SQL_TEXT ,(c.TIMER_END-c.TIMER_START)/1000000000 AS DURATION_ms FROM events_statements_history_long a inner JOIN threads b ON a.THREAD_ID =b.THREAD_ID inner JOIN events_stages_history_long c ON b.THREAD_ID=c.THREAD_ID AND c.EVENT_ID BETWEEN a.EVENT_ID AND a.END_EVENT_ID WHEREa.EVENT_NAME= 'statement/sql/select' and (c.TIMER_END-c.TIMER_START)/1000000000>4000 ORDER BY a.THREAD_ID,c.EVENT_ID;
    

1.2.3 使用explain分析执行计划

1.3 服务器层面优化

1.3.1 服务器硬件优化

提升硬件设备,例如选择尽量高频率的内存(频率不能高于主板的支持)、提升网络带宽、使用SSD高速磁盘、提升CPU性能等。

CPU的选择:

  • 对于数据库并发比较高的场景,CPU的数量比频率重要。

  • 对于CPU密集型场景和频繁执行复杂SQL的场景,CPU的频率越高越好。

1.3.2 配置参数优化

  • 设置足够大的 innodb_buffer_pool_size ,将数据读取到内存中,建议设置为总内存大小的3/4或者4/5

  • 对于生产环境来说,很多日志是不需要开启的,建议关闭,比如:通用查询日志、慢查询日志、错误日志

  • 使用足够大的写入缓存 innodb_log_file_size,推荐设置为 0.25 * innodb_buffer_pool_size,过大,实例恢复时间长;过小,造成频繁脏页落盘

  • 设置合适的innodb_flush_log_at_trx_commit,和redo日志落盘有关系如果该机器不是作为写操作的机器(读写分离的情况),该参数设置为0

  • sync_binlog控制binlog写入策略,如果该机器不是作为写操作的机器(读写分离的情况),该参数设置为0,否则建议设置为1

  • 脏页占innodb_buffer_pool_size的比例innodb_max_dirty_pages_pct达到阈值,触发刷脏页到磁盘,建议设置为25%-50%

  • 设置后台进程最大IO性能指标innodb_io_capacity,默认200,如果SSD,调整为5000~20000

  • 指定innodb共享表空间文件的路径innodb_data_file_path

    首先,5.7之后,默认都是使用独占表空间。而像undo log相关的数据还是存储到共享表空间。而共享表空间是只增大不缩小的一个文件。如果电脑安装了多块磁盘,可以指定共享表空间存储到哪些磁盘上面。

  • 慢查询日志的阈值设置,单位秒,long_qurey_time=0.8

  • mysql复制的形式,binlog_format=row为MySQL8.0的默认形式 MySQL进行主从复制的时候,binlog有多种数据格式:基础段的格式、基于行的格式、混合格式

  • 调高参数max_connections则应降低interactive_timeout、wait_timeout的值

    默认是200,一般建议生产调整为2000左右。

    最大连接数的提高,其实也就是提高了数据库的并发能力。但是并发能力的提高不能只是考虑连接数的调大,因为连接数大了,使用的内存也就多了。

  • 全量日志建议关闭general_log=0,默认关闭

1.3.3 SQL语句优化

  • 设计中间表,一般针对于统计分析功能,或者实时性不高的需求(OLTP、OLAP)

  • 为减少关联查询,创建合理的冗余字段(考虑数据库的三范式和查询性能的取舍,创建冗余字段还需要注意数据一致性问题)

  • 对于字段太多的大表,考虑拆表(比如一个表有100多个字段)

  • 对于表中经常不被使用的字段或者存储数据比较多的字段,考虑拆表(比如商品表中会存储商品介绍,此时可以将商品介绍字段单独拆解到另一个表中,使用商品ID关联)

  • 每张表建议都要有一个主键(主键索引),而且主键类型最好是int类型,建议自增主键(不考虑分布式系统的情况下)。

  • 索引优化

  • limit 优化

    如果预计SELECT语句的查询结果是一条,最好使用 LIMIT 1,可以停止全表扫描

    处理分页会使用到 LIMIT ,当翻页到非常靠后的页面的时候,偏移量会非常大,这时LIMIT的效率会非常差,此时可以使用下列解决方案:

    1. 使用order by 和索引覆盖

      #原SQL(如果 film 表中的记录有10020条)
      SELECT id,name FROM user LIMIT 10000, 20;
      
      #优化的SQL
      SELECT id,name FROM user where id>10000 ORDER BY title LIMIT 20;
      
    2. 使用子查询

    3. 单表分页时,使用自增主键排序之后,先使用where条件 id > offset值,limit后面只写rows

  • join时小表驱动大表

  • 尽量不使用count(*)、尽量使用count(主键)

  • WHERE条件中尽量不要使用1=1、not in语句(建议使用not exists)

  • 不用 MYSQL 内置的函数,因为内置函数不会建立查询缓存

  • 在互联网项目中,一般都不建议使用外键

  • 合理利用慢查询日志、explain执行计划查询、show profile查看SQL执行时的资源使用情况

1.4 集群搭建主从复制

1.4.1 主从复制原理简介

主从复制是基于binlog日志实现的。所以必须开启binlog日志log-bin=binlog日志文件的前缀。

binlog介绍和relay日志

binlog默认是不开启的,需要手动开启。

binlog中的数据,是事务提交才会写入的。

binlog日志是属于MySQL Server层的,不是存储引擎层实现的。

binlog的日志格式由三种:基于row的,基于statement的、混合的mixed

建议使用的是基于row的,同时设置binlog_row_image属性为full|blob|minimal。建议设置为minimal

查看bin log和relay log日志:

mysqlbinlog --base64-output=decode-rows -v -v mysql-bin.000058 > binlog

1.4.2 配置主服务器

  • 关闭主从机器的防火墙

    systemctl stop iptables(需要安装iptables服务) 
    systemctl stop firewalld(默认)
    systemctl disable firewalld.service(设置开启不启动)
    
  • 修改my.conf文件

    #启用二进制日志 
    log-bin=mysql-bin 
    #服务器唯一ID,一般取IP最后一段 
    server-id=133
    
  • 重启mysql服务

    systemctl restart mysqld
    
  • 主机给从机授备份权限

    #一般不用root帐号,“%”表示所有客户端都可能连,只要帐号,密码正确,此处可用具体客户端IP代替,如192.168.145.226,加强安全。
    mysql>GRANT REPLICATION SLAVE ON *.* TO '从机MySQL用户名'@'从机IP' identified by '从机MySQL密码';
    
  • 刷新权限

    mysql> FLUSH PRIVILEGES;
    
  • 查询master的状态

    mysql> show master status; 
    +------------------+-- -------+--------------+------------------+ 
    | File | Position | Binlog_Do_DB | Binlog_Ignore_DB 
    | +------------------+----------+--------------+------------------+ 
    | mysql-bin.000001 | 410 | db1 | mysql 
    | +------------------+----------+--------------+------------------+ 
    
    1 row in set
    

1.4.3 配置从服务器

  • 修改my.conf文件

    [mysqld]
    server-id=135
    
  • 删除UUID文件,防止启动报错

    删除/var/lib/mysql/auto.cnf文件,重新启动MySQL服务。因为是mysql是克隆的系统所以mysql的uuid是一样的,所以需要修改。

  • 重启并登录到MySQL进行配置从服务器

    #语句中间不要断开, master_port 为mysql服务器端口号(无引号), master_user 为执行同步操作的
    #数据库账户, “410” 无单引号(此处的 410 就是 show master status 中看到的 position 的值,这
    #里的 mysql-bin.000001 就是 file 对应的值)。
    mysql>change master to 
    	master_host='192.168.211.128', 
    	master_port=3306, 
    	master_user='root', 
    	master_password='root', 
    	master_log_file='mysql-bin.000001', 
    	master_log_pos=397
    
  • 启动从服务器复制功能

    mysql>start slave;
    
  • 检查从服务器复制功能状态

    # 结果中 Slave_IO_Running: Yes // 此状态必须YES 
    # Slave_SQL_Running: Yes //此状态必须YES 
    mysql> show slave status \G; 
    

1.4.4 主从复制延迟解决方案

mysql 用主从同步的方法进行读写分离,减轻主服务器的压力的做法现在在业内做的非常普遍。 主从同步基本上能做到实时同步。在配置好了, 主从同步以后, 主服务器会把更新语句写入binlog, 从服务器的IO 线程(这里要注意, 5.6.3 之前的IO线程仅有一个,5.6.3之后的有多线程去读了,速度自然也就加快了)会去读取主服务器的binlog 并且写到从服务器的Relay log 里面然后从服务器的SQL thread 会一个一个执行 relay log 里面的sql , 进行数据恢复

  • 主从同步的延迟的原因

    一个服务器开放N个链接给客户端来连接的,这样有会有大并发的更新操作, 但是从服务器的里面读取binlog 的线程仅有一个, 当某个SQL在从服务器上执行的时间稍长或者由于某个SQL要进行锁表就会导致,主服务器的SQL大量积压,未被同步到从服务器里。这就导致了主从不一致, 也就是主从延迟。

  • 判定方法

    MySQL提供了从服务器状态命令,可以通过 show slave status 进行查看, 可以根据Seconds_Behind_Master参数的值来判断,是否有发生主从延时。

    其值有这么几种:

    NULL : 表示io_thread或是sql_thread有任何一个发生故障,也就是该线程的Running状态是No,而非Yes.

    0 : 该值为零,是我们极为渴望看到的情况,表示主从复制状态正常

  • 解决办法(缓解方案)

    1. slave不需要高级别的数据安全,可以将sync_binlog设置为0或关闭binlog,innodb_flushlog, innodb_flush_log_at_trx_commit 也可以设置为0来提高sql的执行效率

    2. 使用比主库更好的硬件设备作为slave

    3. 把一台从服务器当度作为备份使用, 而不提供查询, 用来执行relaylog 里面的SQL恢复工作,效率自然就高了

    4. 增加从服务器喽,这个目的还是分散读的压力, 从而降低服务器负载

2、分库分表策略

2.1 分库分表原因

关系型数据库以MySQL为例,单机的存储能力、连接数是有限的,它自身就很容易会成为系统的瓶颈。当单表数据量在百万以里时,我们还可以通过添加从库、优化索引提升性能。一旦数据量朝着千万以上趋势增长,再怎么优化数据库,很多操作性能仍下降严重。为了减少数据库的负担,提升数据库响应速度,缩短查询时间,这时候就需要进行 分库分表 。

当【表的数量】达到了几百上千张表时,众多的业务模块都访问这个数据库,压力会比较大,考虑对其进行分库。

当【表的数据】达到了几千万级别,在做很多操作都比较吃力,所以,考虑对其进行分库或者分表。

2.2 数据切分方案

数据的切分(Sharding)根据其切分规则的类型,可以分为两种切分模式:

  • 垂直切分:按照业务模块进行切分,将不同模块的表切分到不同的数据库中。

  • 水平切分:将一张大表按照一定的切分规则,按照行切分成不同的表或者切分到不同的库中。

2.3 数据切分规则配置

常用的切分规则有以下几种:

  • 按照ID取模:对ID进行取模,余数决定该行数据切分到哪个表或者库中

  • 按照日期:按照年月日,将数据切分到不同的表或者库中

  • 按照范围:可以对某一列按照范围进行切分,不同的范围切分到不同的表或者数据库中

2.4 分库分表需要解决的问题

  • 分布式事务问题

    强一致性事务(同步)

    最终一致性事务(异步思想)

  • 分布式主键问题

    redis incr命令

    数据库(生成主键)

    UUID

    snowflake算法

  • 跨库join问题

    通过业务分析,将不同库的join查询拆分成多个select

    建立全局表(每个库都有一个相同的表)

    冗余字段(不符合数据库三范式)

    E-R分片(将有ER关系的记录都存储到一个库中)

    最多支持跨两张表跨库的join

  • 跨库count、order by、group by问题

2.5 分库分表方案Sharding JDBC

  • 分片算法

    通过分片算法将数据分片,支持通过 = 、 BETWEEN 和 IN 分片。分片算法需要应用方开发者自行实现,可实现的灵活度非常高。

    精确分片算法(PreciseShardingAlgorithm) 用于处理使用单一键作为分片键的=与IN进行分片的场景。需要配合StandardShardingStrategy使用。

    范围分片算法(RangeShardingAlgorithm) 用于处理使用单一键作为分片键的BETWEEN AND进行分片的场景。需要配合StandardShardingStrategy使用。

    复合分片算法(ComplexKeysShardingAlgorithm) 用于处理使用多键作为分片键进行分片的场景,包含多个分片键的逻辑较复杂,需要应用开发者自行处理其中的复杂度。需要配合ComplexShardingStrategy使用。

    Hint分片算法(HintShardingAlgorithm) 用于处理使用Hint行分片的场景。需要配合HintShardingStrategy使用。

  • 分片策略

    标准分片策略(StandardShardingStrategy) 提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持。StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法。PreciseShardingAlgorithm是必选的,用于处理=和IN的分片。RangeShardingAlgorithm是可选的,用于处理BETWEEN AND分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND将按照全库路由处理。

    复合分片策略(ComplexShardingStrategy) 提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。

    行表达式分片策略(InlineShardingStrategy) 使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发。行表达式的使用非常直观,只需要在配置中使用 expression{ expression } 或 ->{ expression } 标识行表达式即可。 目前支持数据节点和分片算法这两个部分的配置。行表达式的内容使用的是Groovy的语法,Groovy能够支持的所有操作,行表达式均能够支持。

    Hint分片策略(HintShardingStrategy) 通过Hint而非SQL解析的方式分片的策略。对于分片字段非SQL决定,而由其他外置条件决定的场景,可使用SQL Hint灵活的注入分片字段。例:内部系统,按照员工登录主键分库,而数据库中并无此字段。SQL Hint支持通过Java API和SQL注释(待实现)两种方式使用。

  • 配置内容

    分片规则 :分片规则配置的总入口。包含数据源配置、表配置、绑定表配置以及读写分离配置等。

    数据源配置 :真实数据源列表,结合数据库连接池使用

    表配置 : 逻辑表名称、数据节点与分表规则的配置。

    数据节点配置 : 用于配置逻辑表与真实表的映射关系。可分为均匀分布和自定义分布两种形式。

    分片策略配置 : 对于分片策略存有数据源分片策略和表分片策略两种维度。

    数据源分片策略 :对应于DatabaseShardingStrategy。用于配置数据被分配的目标数据源。

    表分片策略 :对应于TableShardingStrategy。用于配置数据被分配的目标表,该目标表存在与该数据的目标数据源内。故表分片策略是依赖与数据源分片策略的结果的。

    自增主键生成策略 :通过在客户端生成自增主键替换以数据库原生自增主键的方式,做到分布式主键无重复。(UUID和雪花算法)

2.6 分库分表方案Mycat

  • Mycat核心概念

    ​ Schema:由它指定逻辑数据库(相当于MySQL的database数据库)

    ​ Table:逻辑表(相当于MySQL的table表)

    ​ DataNode:真正存储数据的物理节点

    ​ DataHost:存储节点所在的数据库主机(指定MySQL数据库的连接信息)

    ​ User:MyCat的用户(类似于MySQL的用户,支持多用户)

  • Mycat主要解决的问题

    ​ 海量数据存储

    ​ 查询优化

  • Mycat分片策略

    MyCAT支持水平分片与垂直分片:

    水平分片:一个表格的数据分割到多个节点上,按照行分隔。

    垂直分片:一个数据库中多个表格A,B,C,A存储到节点1上,B存储到节点2上,C存储到节点3上。

    具体配置说明本文不再进行详述,请参考官网mycat.sourceforge.net/