mycat学习

一 数据库性能优化

数据库性能瓶颈主要原因

1,数据库连接

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

​ 索引

​ 命中不了 全表的扫描

命中索引

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

3,硬件资源限制(QPS\TPS)

数据性能优化方案

1,sql优化

2,缓存

3,建好索引

4,读写分离

5,分库分表

读写分离

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

image-20200725044404324

1,数据库连接

2,硬件资源限制(QPS\TPS)

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

image-20200725044747980

分库分表

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

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

垂直拆分

image-20200725045052534

​ 1,数据库连接

​ 2,硬件资源限制(QPS\TPS)

水平拆分

image-20200725045210794

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

​ 1,数据库连接

​ 2,硬件资源限制(QPS\TPS)

二 mycat

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

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

image-20200725045644770

逻辑库 db_user db_store

逻辑表

​ 分片表 用户表

​ 全局表 数字字典表

​ ER表 用户地址表

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

分片规则 userID%2

节点

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

主从复制原理

image-20200725054330199

  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 status\G ;查看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目录

image-20200725055336090

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

连续分片

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

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

代表:

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

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

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

<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

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

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

<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>

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

<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个分片,一个月完后下月从头开始循环。

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

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

离散分片

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

缺点:移植性差,扩容难

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

离散分片之枚举分片

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

<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)
默认节点的作用:枚举分片时,如果碰到不识别的枚举值,就让它路由到默认节点

离散分片之十进制取模

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

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

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

<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分片

<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分片:
此规则优点在于扩容时迁移数据量比较少,前提分片节点比较多,虚拟节点分配多些。
虚拟节点少的缺点是会造成数据分布不够均匀
如果实际分片数量比较少,迁移量会比较多

<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

综合类分片

兼并二者

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

综合分片之范围求模分片

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

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

<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

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

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

<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%256后分布的范围。
如果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之注解

/*!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.使用注解

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

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

五 Mycat命令行监控工具

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

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:\Users\huayu\AppData\Roaming\Typora\typora-user-images\image-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是七层负载

image-20200726084246203

灵魂拷问:

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

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

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

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

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

* 概述一下mycat?

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

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

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

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

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

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

* 讲一讲高可用方案

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值