mycat学习

2022-10-25 16:44:51 浏览数 (2)

文章目录
  • 一 数据库性能优化
    • 数据库性能瓶颈主要原因
    • 数据性能优化方案
    • 读写分离
    • 分库分表
      • 垂直拆分
      • 水平拆分
  • 二 mycat
    • 主从复制原理
    • 配置主从
    • 主从复制的延迟
  • mycat 配置文件
    • mycat目录
    • 1.schema.xml
    • 2.server.xml
    • rule.xml
      • 连续分片
        • 连续分片之自定义数字范围分片
        • 连续分片之按日期(天,月)分片
        • 连续分片之按单月小时分片
      • 离散分片
        • 离散分片之枚举分片
        • 离散分片之十进制取模
        • 离散分片之应用指定分片
        • 离散分片之字符串截取数字hash分片
        • 离散分片之一致性Hash分片
        • 理解一致性Hash
      • 综合类分片
        • 综合分片之范围求模分片
        • 综合分片之取模范围约束分片
      • 分片取舍
      • 分片选择总结
  • 三 全局序列
  • 四 Mycat之注解
  • 五 Mycat命令行监控工具
  • 六 Mycat弱XA事务机制
  • 七 Mycat之节点扩缩容
  • 八 Mycat之mysqldump方式进行快速移植
  • 九 mycat之高可用

一 数据库性能优化

数据库性能瓶颈主要原因

1,数据库连接

2,表数据量(空间存储的问题)

​ 索引

​ 命中不了 全表的扫描

代码语言:javascript复制
命中索引

​ 硬盘级索引,它是存储在硬盘里面 IO操作

3,硬件资源限制(QPSTPS)

数据性能优化方案

1,sql优化

2,缓存

3,建好索引

4,读写分离

5,分库分表

读写分离

区别读、写多数据源方式进行数据的存储和加载。 数据的存储(增删改)一般指定写数据源,数据的读取查询指定读数据源(读写分离会基于主从复制)

1,数据库连接

2,硬件资源限制(QPSTPS)

主从形式 有 一主一从 互为主从 一主多从 级联多从

分库分表

对数据的库表进行拆分,用分片的方式对数据进行管理。

按拆分规则分为垂直拆分和水平拆分

垂直拆分

​ 1,数据库连接

​ 2,硬件资源限制(QPSTPS)

水平拆分

​ 1,表数据量大的问题 存储空间也解决了

​ 1,数据库连接

​ 2,硬件资源限制(QPSTPS)

二 mycat

Mycat 是开源的分布式数据库中间件,基于阿里的cobar的开源框架之上。它处于数据库服务与应用服务之间。它是进行数据处理与整合的中间服务。

通俗点讲,应用层可以将它看作是一个数据库的代理(或者直接看成加强版数据库)

逻辑库 db_user db_store

逻辑表

​ 分片表 用户表

​ 全局表 数字字典表

​ ER表 用户地址表

​ 非分片表 门店表,店员表

分片规则 userID%2

节点

节点主机(写、读节点主机)

主从复制原理

  1. master将操作记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events)
  2. Slave通过I/O Thread异步将master的binary log events拷贝到它的中继日志(relay log);
  3. Slave执行relay日志中的事件,匹配自己的配置将需要执行的数据,在slave服务上执行一遍从而达到复制数据的目的。

配置主从

Master操作:

  1. 接入mysql并创建主从复制的用户 create user m2ssync identified by ‘Qq123!@#’;
  2. 给新建的用户赋权 GRANT REPLICATION SLAVE ON . TO ‘m2ssync’@’%’ IDENTIFIED BY ‘Qq123!@#’;
  3. 指定服务ID,开启binlog日志记录,在my.cnf中加入 server-id=137 log-bin=dbstore_binlog binlog-do-db=db_store
  4. 通过SHOW MASTER STATUS;查看Master db状态.

Slave操作: 1.指定服务器ID,指定同步的binlog存储位置,在my.cnf中加入

server-id=101

relay-log=slave-relay-bin

relay-log-index=slave-relay-bin.index

read_only=1

replicate_do_db=db_store

2.接入slave的mysql服务,并配置change master to master_host=‘192.168.8.137’, master_port=3306,master_user=‘m2ssync’,master_password=‘Qq123!@#’,master_log_file=‘db_store_binlog’,master_log_pos=0;

3.start slave;

4.show slave statusG ;查看slave服务器状态

主从复制的延迟

延迟是怎么产生的

1,当master tps高于slave的sql线程所能承受的范围

2,网络原因

3,磁盘读写耗时

判断延迟?

1,show slave status G; sends_behind_master 0

2, mk-heartbeat timestamp进行实践搓的判断

我们怎么解决延迟问题

1,配置更高的硬件资源

2,把IOthread 改变成 多线程的方式

​ mysql5.6 库进行多线程的方式

​ GTID进行多线程的方式

3, 应用程序自己去判断(mycat有这么方案)

mycat 配置文件

mycat目录

bin 程序目录,存放了 window 版本和 linux 版本可执行文件./mycat {start|restart|stop|status…}

conf 目录下存放配置文件,

server.xml 是 Mycat 服务器参数调整和用户授权的配置文件

schema.xml 是逻辑库定义和表以及分片定义的配置文件

rule.xml 是分片规则的配置文件,分片规则的具体一些参数信息单独存放为文件,也在 这个目录下

log4j2.xml配置logs目录日志输出规则

wrapper.conf JVM相关参数调整

lib 目录下主要存放 mycat 依赖的一些 jar 文件

logs目录日志存放日志文件

1.schema.xml

dataHost

​ balance:

​ 负载/读写分离 均衡类型。

​ 取值为

​ balance=“0”, 不开启读写分离机制,所有读操作都发送到当前可用的 writeHost 上。

​ balance=“1”,全部的 readHost 与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双

主双从模式(M1->S1,M2->S2,并且 M1 与 M2 互为主备),正常情况下,M2,S1,S2 都参与 select 语句的负载

均衡。

​ balance=“2”,所有读操作都随机的在 writeHost、readhost 上分发。

​ switchType

​ 主从切换策略

​ -1 表示不自动切换

​ 1 默认值,自动切换

​ 2 基于 MySQL 主从同步的状态决定是否切换

​ 心跳语句设置为 show slave status

​ 通过检测 show slave status 中的 “Seconds_Behind_Master”, “Slave_IO_Running” “Slave_SQL_Running” 三个字段以及slaveThreshold 设置的值进行判断是否进行主从切换

​ usingDecrypt

​ 可加入usingDecrypt属性来指定密码加密。1开启,0不开启

​ 进入lib目录的Mycat-server-1.6-RELEASE.jar 执行

​ java -cp Mycat-server-1.6-RELEASE.jar io.mycat.util.DecryptUtil 1:host:user:password

​ 1:host:user:password 中 1 为 db 端加密标志,host 为 dataHost 的 host 名称

2.server.xml

sequnceHandlerType

​ 全局序列的方式

firewall

​ 黑白名单设置

user

​ benchmark 当前端连接达到设置的值,不再允许这个用户进行接入

​ 表级的DML权限控制。4位2进制 顺序为 insert update select delete

rule.xml

连续分片

优点:扩容无需迁移数据,范围条件查询资源消耗小

缺点:数据热点问题,并发能力受限于分片节点

代表:

按日期(天)分片 自定义数字范围分片 自然月分片

连续分片之自定义数字范围分片

自定义数字范围分片,提前规划好分片字段某个范围属于哪个分片

代码语言:javascript复制
<function name="rang-long"
		class="io.mycat.route.function.AutoPartitionByLong">
	<property name="mapFile">autopartition-long.txt</property>
	<property name="defaultNode">0</property> 
</function>

defaultNode 超过范围后的默认节点。

此配置非常简单,即预先制定可能的id范围到某个分片 0-500M=0 500M-1000M=1 1000M-1500M=2 或 0-10000000=0 10000001-20000000=1 注意: 所有的节点配置都是从0开始,及0代表节点1

连续分片之按日期(天,月)分片

按日期(天)分片: 从开始日期算起,按照天数来分片

代码语言:javascript复制
<function name=“sharding-by-date” class=“io.mycat.route.function.PartitionByDate">
	<property name="dateFormat">yyyy-MM-dd</property>      <!--日期格式-->
	<property name="sBeginDate">2014-01-01</property>            <!--开始日期-->
	<property name="sPartionDay">10</property> <!--每分片天数-->
</function>

按日期(自然月)分片: 从开始日期算起,按照自然月来分片

代码语言:javascript复制
<function name=“sharding-by-month” class=“io.mycat.route.function.PartitionByMonth">
	<property name="dateFormat">yyyy-MM-dd</property>        <!--日期格式-->
	<property name="sBeginDate">2014-01-01</property>            <!--开始日期-->
</function>

注意: 需要提前将分片规划好,建好,否则有可能日期超出实际配置分片数

连续分片之按单月小时分片

按单月小时分片:最小粒度是小时,可以一天最多24个分片,最少1个分片,一个月完后下月从头开始循环。

代码语言:javascript复制
<function name="sharding-by-hour" class=“io.mycat.route.function.LatestMonthPartion"> 
	<property name="splitOneDay">24</property> <!-- 将一天的数据拆解成几个分片-->
</function>

注意事项:每个月月尾,需要手工清理数据

离散分片

优点:数据分布均匀,并发能力强,不受限分片节点

缺点:移植性差,扩容难

代表: 枚举分片 数字取模分片 字符串数字hash分片 一致性哈希分片 程序指定

离散分片之枚举分片

枚举分片:通过在配置文件中配置可能的枚举id,自己配置分片,本规则适用于特定的场景,比如有些业务需要按照省份或区县来做保存,而全国省份区县固定的

代码语言:javascript复制
<function name="hash-int" class=“io.mycat.route.function.PartitionByFileMap">
 	<property name="mapFile">partition-hash-int.txt</property> 
	<property name="type">0</property> 
	<property name="defaultNode">0</property> 
</function> 

partition-hash-int.txt 配置: 10000=0 10010=1

mapFile标识配置文件名称 type默认值为0(0表示Integer,非零表示String) 默认节点的作用:枚举分片时,如果碰到不识别的枚举值,就让它路由到默认节点

离散分片之十进制取模

十进制求模分片:规则为对分片字段十进制取模运算。数据分布最均匀

代码语言:javascript复制
<function name="mod-long" class=“io.mycat.route.function.PartitionByMod"> 
	<!-- how many data nodes  --> 
	<property name="count">3</property> 
</function>
离散分片之应用指定分片

应用指定分片:规则为对分片字段进行字符串截取,获取的字符串即指定分片。

代码语言:javascript复制
<function name="sharding-by-substring“ class="io.mycat.route.function.PartitionDirectBySubString">
	<property name="startIndex">0</property><!-- zero-based -->
	<property name="size">2</property>
	<property name="partitionCount">8</property>
	<property name="defaultPartition">0</property>
</function>

startIndex 开始截取的位置 size 截取的长度 partitionCount 分片数量 defaultPartition 默认分片

例如 id=05-100000002 在此配置中代表根据 id 中从 startIndex=0,开始,截取 size=2 位数字即 05,05 就是获取的分区,如果没传 默认分配到 defaultPartition

离散分片之字符串截取数字hash分片

截取数字hash分片 此规则是截取字符串中的int数值hash分片

代码语言:javascript复制
<function name="sharding-by-stringhash" class=“io.mycat.route.function.PartitionByString"> 
	<property name=length>512</property><!-- zero-based --> 
	<property name="count">2</property> 
	<property name="hashSlice">0:2</property>
</function>

length代表字符串hash求模基数,count分区数,其中length*count=1024 hashSlice hash预算位,即根据子字符串中int值 hash运算 0 代表 str.length(), -1 代表 str.length()-1,大于0只代表数字自身 可以理解为substring(start,end),start为0则只表示0 例1:值“45abc”,hash预算位0:2 ,取其中45进行计算 例2:值“aaaabbb2345”,hash预算位-4:0 ,取其中2345进行计算

离散分片之一致性Hash分片

一致性Hash分片: 此规则优点在于扩容时迁移数据量比较少,前提分片节点比较多,虚拟节点分配多些。 虚拟节点少的缺点是会造成数据分布不够均匀 如果实际分片数量比较少,迁移量会比较多

代码语言:javascript复制
<function name="murmur" class=“io.mycat.route.function.PartitionByMurmurHash"> 
	<property name="seed">0</property><!-- 创建hash对象的种子,默认0--> 
	<property name="count">2</property><!-- 要分片的数据库节点数量,必须指定,否则没法分片--> 
	<property name="virtualBucketTimes">160</property>
</function>

注意: 一个实际的数据库节点被映射为这么多虚拟节点,默认是160倍,也就是虚拟节点数是物理节点数的160倍

理解一致性Hash

1.hash(str) { return 0 -> 2^32 },将整个0-2^32的hash值,作为一个hash环。

2.取node唯一标示计算出hash值,该hash结果即node在整个hash环中的位置

3.将数据进行hash计算之后,顺时针找对应的node,改node即为该数据的服务node

综合类分片

兼并二者

代表: 范围求模分片 取模范围约束分片 …

综合分片之范围求模分片

范围求模分片:先进行范围分片计算出分片组,组内再求模。 优点可以避免扩容时的数据迁移,又可以一定程度上避免范围分片的热点问题 分片组内使用求模可以保证组内数据比较均匀,分片组之间是范围分片可以兼顾范围查询。

最好事先规划好分片的数量,数据扩容时按分片组扩容,则原有分片组的数据不需要迁移。 由于分片组内数据比较均匀,所以分片组内可以避免热点数据问题。

代码语言:javascript复制
<function name="rang-mod" class=“io.mycat.route.function.PartitionByRangeMod"> 
	<property name="mapFile">partition-range-mod.txt</property>
 	<property name="defaultNode">32</property> 
</function>

partition-range-mod.txt 以下配置一个范围代表一个分片组,=号后面的数字代表该分片组所拥有的分片的数量。 0-200M=5 //代表有5个分片节点 200M-400M=6 400M-600M=6 600M-800M=8 800M-1000M=7

综合分片之取模范围约束分片

取模范围约束分片: 对指定分片列进行取模后再由配置决定数据的节点分布。

代码语言:javascript复制
<function name="sharding-by-pattern" class=“io.mycat.route.function.PartitionByPattern">
 	<property name="patternValue">256</property>
 	<property name="defaultNode">2</property> 
	<property name="mapFile">partition-pattern.txt</property> 
 </function>

patternValue 即求模基数, defaoultNode 默认节点 partition-pattern.txt配置 1-32=0 33-64=1 65-96=2 97-128=3 128-256=4

配置文件中,1-32 即代表id%6后分布的范围。 如果id非数字,则会分配在defaoultNode 默认节点

分片取舍

数据特点:活跃的数据热度较高规模可以预期,增长量比较稳定

数据特点:活跃的数据为历史数据,热度要求不高。规模可以预期,增长量比较稳定.优势可定时清理或者迁移数据

分片选择总结

1,根据业务数据的特性合理选择分片规则 2,善用全局表、ER关系表解决join操作 3,用好primaryKey让你的性能起飞

三 全局序列

1,本地文件方式

​ sequnceHandlerType = 0 ​ 配置sequence_conf.properties ​ 使用next value for MYCATSEQ_XXX 2,数据库方式 ​ sequnceHandlerType = 1 ​ 配置sequence_db_conf.properties ​ 使用next value for MYCATSEQ_XXX或者指定autoIncrement ​ 3,本地时间戳方式 ​ ID= 64 位二进制 (42(毫秒) 5(机器 ID) 5(业务编码) 12(重复累加) ​ sequnceHandlerType = 2 ​ 配置sequence_time_conf.properties 指定autoIncrement

4, 程序方式 Snowflake UUID Redis …

四 Mycat之注解

代码语言:javascript复制
/*!mycat: sql=select * from users where userID=1*/ select fun()  from dual;

/*!mycat: sql=select * from users where userID=1*/ CALL proc_test();

/*!mycat: sql=select * from users where userID=1*/ insert into users(id,name) select id,name from otherUsers;

/*!mycat: db_type=slave*/ select * from employee

/*!mycat: sql=select 1 from users */ create table ttt(id int);

/*!mycat:catlet=io.mycat.catlets.ShareJoin */

select * from users u,employee em on u.phoneNum=em.phoneNum where u.phoneNum ='13633333333' ;

##Mycat关联查询的问题总结

1.用好ER表 2.善用全局表 3.使用注解

代码语言:javascript复制
/*!mycat:catlet=io.mycat.catlets.ShareJoin */

select * from users u,employee em on u.phoneNum=em.phoneNum where u.phoneNum ='13633333333' ;

五 Mycat命令行监控工具

重载配置文件 查看运行状态 提供性能数据

代码语言:javascript复制
mysql -uuser –ppwd -P9066
show @@help 查看所有命令
reload @@config
reload @@config_all
show @@database
show @@datanode
show @@datasource
show @@cache
show @@connection
show @@connection.sql
show @@backend
kill @@connection id1,id2
show @@heartbeat
show @@sysparam

六 Mycat弱XA事务机制

为什么2PC提交.

  1. 是2PC才会有事务管理器统一管理的机会;
  2. 尽可能晚地提交事务,让事务在提交前尽可能地完成所有能完成的工作,这样,最后的提交阶段将是耗时极短,耗时极短意味着操作失败的可能性也就降低

XA 是一个两阶段提交协议,规定事务协调/管理器和资源管理器接口 二阶段提交协议为了保证事务的一致性,不管是事务管理器还是各个资源管理器,每执行一步操作,都会记录日志,为出现故障后的恢复准备依据

Mycat 第二阶段的提交没有做相关日志的记录,所以说他是一个弱XA的分布式事务解决方案

七 Mycat之节点扩缩容

自带的mycat工具进行扩容缩容

mycat 所在环境安装 mysql 客户端程序

mycat 的 lib 目录下添加 mysql 的 jdbc 驱动包

对扩容缩容的表所有节点数据进行备份,以便迁移失败后的数据恢复

编辑newSchema.xml 和 newRule.xml

配置conf/migrateTables.properties

修改bin/dataMigrate.sh,执行dataMigrate.sh

注意前方坑位【坑坑坑】: 1,一旦执行数据是不可逆的 2,只能支持分片表的扩缩容 3,分片规则必须一致,只能节点扩或者缩

八 Mycat之mysqldump方式进行快速移植

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FAJtd1wW-1595724430095)(C:UsershuayuAppDataRoamingTyporatypora-user-imagesimage-20200725201119496.png)]

mysqldump方式

导出数据 mysqldump -uroot -p123456 -h192.168.8.137 -c db_user_old users > users.sql ER子表 mysqldump -uroot -p123456 -h192.168.8.137 -c --skip-extended-insert db_user_old user_address > userAddress.sql 导入 mysql -h192.168.8.151 -uroot -p123456 -P8066 -f db_user < users.sql mysql -h192.168.8.151 -uroot -p123456 -P8066 -f db_user < userAddress.sql

九 mycat之高可用

Haproxy四层负载

四层负载均衡

​ 四层负载均衡也称为四层交换机,它主要是通过分析IP层及TCP/UDP层的流量实现的基于IP加端口的负载均衡 LVS,F5是四层负载

七层负载均衡

​ 七层负载均衡器也称为七层交换机,位于OSI( Open System Interconnection ,开放式系统互联)的最高层,即应用层,此时负载均衡器支持多种应用协议,常见的有HTTP、FTP、SMTP等 haproxy Nginx是七层负载

灵魂拷问:

* 单表数据达到多少的时候会影响数据库的查询性能?为什么?

* 主从复制机制的原理概述是怎样的?常见的存在形式有哪些?

* 分库分表中解释一下垂直和水平2种不同的拆分?

* 分库分表中垂直分库方案会带来哪些问题?

* 分布式数据存储中间件如mycat的核心流程是什么?

* 概述一下mycat?

* 解释一下全局表,ER表,分片表?

* Mycat的在分库分表之后,它是怎么支持联表查询的?

* 进行库表拆分时,拆分规则怎么取舍?

* Mycat中全局ID方案有哪些?程序自定义全局ID的方案有哪些?

* 简述一下一致性hash的原理?这样设计的好处是什么?

* 4层负载和7层负载谁性能更高?为什么?这2者区别是什么?

* 讲一讲高可用方案

0 人点赞