Mycat 是什么?从定义和分类来看,它是一个开源的分布式数据库系统,是一个实现了MySQL 协议的的Server,前端用户可以把它看作是一个数据库代理,用MySQL 客户端工具和命令行访问,而其后端可以用MySQL 原生(Native)协议与多个MySQL 服务器通信,也可以用JDBC 协议与大多数主流数据库服务器通信,其核心功能是分表分库,即将一个大表水平分割为N 个小表,存储在后端MySQL 服务器里或者其他数据库里。
Mycat 发展到目前的版本,已经不是一个单纯的MySQL 代理了,它的后端可以支持MySQL、SQLServer、Oracle、DB2、PostgreSQL 等主流数据库,也支持MongoDB 这种新型NoSQL 方式的存储,未来还会支持更多类型的存储。而在最终用户看来,无论是那种存储方式,在Mycat 里,都是一个传统的数据库表,支持标准的SQL 语句进行数据的操作,这样一来,对前端业务系统来说,可以大幅降低开发难度,提升开发速度。
Mycat 就是MySQL Server,而Mycat 后面连接的MySQL Server,就好象是MySQL 的存储引擎,如InnoDB,MyISAM 等,因此,Mycat 本身并不存储数据,数据是在后端的MySQL 上存储的,因此数据可靠性以及事务等都是MySQL 保证的。
Mycat 就是一个近似等于MySQL 的数据库服务器,可以用连接MySQL 的方式去连接Mycat(除了端口不同,默认的Mycat 端口是8066 而非MySQL 的3306,因此需要在连接字符串上增加端口信息),大多数情况下,可以用你熟悉的对象映射框架使用Mycat。
Mycat 是一个强大的数据库中间件,不仅仅可以用作读写分离、以及分表分库、容灾备份,而且可以用于多租户应用开发、云平台基础设施、让你的架构具备很强的适应性和灵活性。
Mycat 的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的SQL 语句,首先对SQL 语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL 发往后端的真实数据库,
Orders 表被分为三个分片datanode(简称dn),这三个分片是分布在两台MySQL Server 上(DataHost),即datanode=database@datahost 方式,因此你可以用一台到N 台服务器来分片,分片规则为(sharding rule)典型的字符串枚举分片规则,一个规则的定义是分片字段(sharding column)+分片函数(rulefunction),这里的分片字段为prov 而分片函数为字符串枚举方式。
当Mycat 收到一个SQL 时,会先解析这个SQL,查找涉及到的表,然后看此表的定义,如果有分片规则,则获取到SQL 里分片字段的值,并匹配分片函数,得到该SQL 对应的分片列表,然后将SQL 发往这些分片去执行,最后收集和处理所有分片返回的结果数据,并输出到客户端。以select * from Orders where prov=?语句为例,查到prov=wuhan,按照分片函数,wuhan 返回dn1,于是SQL 就发给了MySQL1,去取DB1 上的查询结果,并返回给用户。
如果上述SQL 改为select * from Orders where prov in (‘wuhan’,‘beijing’),那么,SQL 就会发给MySQL1 与MySQL2 去执行,然后结果集合并后输出给用户。但通常业务中我们的SQL 会有Order By 以及Limit 翻页语法,此时就涉及到结果集在Mycat 端的二次处理。
既然有逻辑库,那么就会有逻辑表,分布式数据库中,对应用来说,读写数据的表就是逻辑表。逻辑表,可以是数据切分后,分布在一个或多个分片库中,也可以不做数据切分,不分片,只有一个表构成。
关系型数据库是基于实体关系模型(Entity-Relationship Model)之上,通过其描述了真实世界中事物与关系,Mycat 中的ER 表即是来源于此。根据这一思路,提出了基于E-R 关系的数据分片策略,子表的记录与所关联的父表记录存放在同一个数据分片上,即子表依赖于父表,通过表分组(Table Group)保证数据Join 不会跨库操作。
对于这类的表,在分片的情况下,当业务表因为规模而进行分片以后,业务表与这些附属的字典表之间的关联,就成了比较棘手的问题,所以Mycat 中通过数据冗余来解决这类表的join,即所有的分片都有一份数据的拷贝,所有将字典表或者符合字典表特性的一些表定义为全局表。
数据切分后,每个分片节点(dataNode)不一定都会独占一台机器,同一机器上面可以有多个分片数据库,这样一个或多个分片节点(dataNode)所在的机器就是节点主机(dataHost),为了规避单节点主机并发数限制,尽量将读写压力高的分片节点(dataNode)均衡的放在不同的节点主机(dataHost)。
前面讲了数据切分,一个大表被分成若干个分片表,就需要一定的规则,这样按照某种业务规则把数据分到某个分片的规则就是分片规则,数据切分选择合适的分片规则非常重要,将极大的避免后续数据处理的难度。
数据切分后,原有的关系数据库中的主键约束在分布式条件下将无法使用,因此需要引入外部机制保证数据唯一性标识,这种保证全局性的数据唯一标识的机制就是全局序列号(sequence)
MyCAT 是使用JAVA 语言进行编写开发,使用前需要先安装JAVA 运行环境(JRE),由于MyCAT 中使用了JDK7 中的一些特性,所以要求必须在JDK7 以上的版本上运行。同时Mysql建议使用5.5以上版本,5.6为宜。
conf 目录下存放配置文件,server.xml 是Mycat 服务器参数调整和用户授权的配置文件,schema.xml 是逻辑库定义和表以及分片定义的配置文件,rule.xml 是分片规则的配置文件,分片规则的具体一些参数信息单独存放为文件,也在这个目录下,配置文件修改,需要重启Mycat 或者通过9066 端口reload.
lib 目录下主要存放mycat 依赖的一些jar 文件.
日志存放在logs/mycat.log 中,每天一个文件,日志的配置是在conf/log4j.xml 中,根据自己的需要,可以调整输出级别为debug,debug 级别下,会输出更多的信息,方便排查问题。
MyCAT 自身有类似其他数据库的管理监控方式,可以通过Mysql 命令行,登录管理端口(9066)执行相应的SQL 进行管理,也可以通过jdbc 的方式进行远程连接管理。
Schema.xml 作为MyCat 中重要的配置文件之一,管理着MyCat 的逻辑库、表、分片规则、DataNode 以及DataSource。弄懂这些配置,是正确使用MyCat 的前提。
schema 标签用于定义MyCat 实例中的逻辑库,MyCat 可以有多个逻辑库,每个逻辑库都有自己的相关配置。可以使用schema 标签来划分这些不同的逻辑库。
如上所示的配置就配置了两个不同的逻辑库,逻辑库的概念和MYSQL 数据库中Database 的概念相同,我们在查询这两个不同的逻辑库中表的时候需要切换到该逻辑库下才可以查询到所需要的表。
那么现在tuser 就绑定到dn1 所配置的具体database 上,可以直接访问这个database,没有配置的表则会走默认节点dn2,这里注意没有配置在分片里面的表工具查看无法显示,但是可以正常使用。
checkSQLschema
当该值设置为true 时,如果我们执行语句select * from TESTDB.travelrecord;则MyCat 会把语句修改为select * from travelrecord;。即把表示schema 的字符去掉,避免发送到后端数据库执行时报错。
不过,即使设置该值为true ,如果语句所带的是并非是schema 指定的名字,例如:**select * from db1.travelrecord;** 那么MyCat 并不会删除db1 这个字段,如果没有定义该库的话则会报错,所以在提供SQL语句的最好是不带这个字段。
sqlMaxLimit
当该值设置为某个数值时。每条执行的SQL 语句,如果没有加上limit 语句,MyCat 也会自动的加上所对应的值。例如设置值为100,执行**select * from TESTDB.travelrecord;**的效果为和执行**select * from TESTDB.travelrecord limit 100;**相同。
不设置该值的话,MyCat 默认会把查询到的信息全部都展示出来,造成过多的输出。所以,在正常使用中,还是建议加上一个值,用于减少过多的数据返回。
当然SQL 语句中也显式的指定limit 的大小,不受该属性的约束。
table 标签
Table 标签定义了MyCat 中的逻辑表,所有需要拆分的表都需要在这个标签中定义。
table 标签的相关属性:
name 属性
定义逻辑表的表名,这个名字就如同我们在数据库中执行create table 命令指定的名字一样,同个schema 标签中定义的名字必须唯一。
dataNode 属性
定义这个逻辑表所属的dataNode, 该属性的值需要和dataNode 标签中name 属性的值相互对应。如果需要定义的dn 过多可以使用如下的方法减少配置:
rule 属性
该属性用于指定逻辑表要使用的规则名字,规则名字在rule.xml 中定义,必须与tableRule 标签中name 属性属性值一一对应。
ruleRequired 属性
该属性用于指定表是否绑定分片规则,如果配置为true,但没有配置具体rule 的话,程序会报错。
primaryKey 属性
该逻辑表对应真实表的主键,例如:分片的规则是使用非主键进行分片的,那么在使用主键查询的时候,就会发送查询语句到所有配置的DN 上,如果使用该属性配置真实表的主键。难么MyCat 会缓存主键与具体DN 的信息,那么再次使用非主键进行查询的时候就不会进行广播式的查询,就会直接发送语句给具体的DN,但是尽管配置该属性,如果缓存并没有命中的话,还是会发送语句给具体的DN,来获得数据。
type 属性
该属性定义了逻辑表的类型,目前逻辑表只有“全局表”和”普通表”两种类型。对应的配置:
全局表:global。
普通表:不指定该值为globla 的所有表。
autoIncrement 属性
mysql 对非自增长主键,使用last_insert_id()是不会返回结果的,只会返回0。所以,只有定义了自增长主键的表才可以用last_insert_id()返回主键值。
mycat 目前提供了自增长主键功能,但是如果对应的mysql 节点上数据表,没有定义auto_increment,那么在mycat 层调用last_insert_id()也是不会返回结果的。
由于insert 操作的时候没有带入分片键,mycat 会先取下这个表对应的全局序列,然后赋值给分片键。这样才能正常的插入到数据库中,最后使用last_insert_id()才会返回插入的分片键值。如果要使用这个功能最好配合使用数据库模式的全局序列。
使用autoIncrement=“true” 指定这个表有使用自增长主键,这样mycat 才会不抛出分片键找不到的异常。
使用autoIncrement=“false” 来禁用这个功能,当然你也可以直接删除掉这个属性。默认就是禁用的。
subTables
使用方式添加subTables="t_order$1-2,t_order3"。
目前分表1.6 以后开始支持并且dataNode 在分表条件下只能配置一个,分表条件下不支持各种条件的join 语句。
needAddLimit 属性
指定表是否需要自动的在每个语句后面加上limit 限制。由于使用了分库分表,数据量有时会特别巨大。这时候执行查询语句,如果恰巧又忘记了加上数量限制的话。那么查询所有的数据出来,也够等上一小会儿的。
所以,mycat 就自动的为我们加上LIMIT 100。当然,如果语句中有limit,就不会在次添加了。这个属性默认为true,你也可以设置成false禁用掉默认行为。
childTable 标签
childTable 标签用于定义E-R 分片的子表。通过标签上的属性与父表进行关联。
childTable 标签的相关属性:
name 属性
定义子表的表名。
joinKey 属性
插入子表的时候会使用这个列的值查找父表存储的数据节点。
parentKey 属性
属性指定的值一般为与父表建立关联关系的列名。程序首先获取joinkey 的值,再通过parentKey 属性指定的列名产生查询语句,通过执行该语句得到父表存储在哪个分片上。从而确定子表存储的位置。
primaryKey 属性
同table 标签所描述的。
needAddLimit 属性
同table 标签所描述的。
dataNode 标签
dataNode 标签定义了MyCat 中的数据节点,也就是我们通常说所的数据分片。一个dataNode 标签就是一个独立的数据分片。
例子中所表述的意思为:使用名字为lch3307 数据库实例上的db1 物理数据库,这就组成一个数据分片,最后,我们使用名字dn1 标识这个分片。
dataNode 标签的相关属性:
name 属性
定义数据节点的名字,这个名字需要是唯一的,我们需要在table 标签上应用这个名字,来建立表与分片对应的关系。
dataHost 属性
该属性用于定义该分片属于哪个数据库实例的,属性值是引用dataHost 标签上定义的name 属性。
database 属性
该属性用于定义该分片属性哪个具体数据库实例上的具体库,因为这里使用两个纬度来定义分片,就是:实例+具体的库。因为每个库上建立的表和表结构是一样的。所以这样做就可以轻松的对表进行水平拆分。
dataHost 标签
作为Schema.xml 中最后的一个标签,该标签在mycat 逻辑库中也是作为最底层的标签存在,直接定义了具体的数据库实例、读写分离配置和心跳语句。
dataHost 标签的相关属性:
name 属性
唯一标识dataHost 标签,供上层的标签使用。
maxCon 属性
指定每个读写实例连接池的最大连接。也就是说,标签内嵌套的writeHost、readHost 标签都会使用这个属性的值来实例化出连接池的最大连接数。
minCon 属性
指定每个读写实例连接池的最小连接,初始化连接池的大小。
balance 属性
负载均衡类型,目前的取值有:
1. balance="0", 不开启读写分离机制,所有读操作都发送到当前可用的writeHost 上。
2. balance="1",全部的readHost 与stand by writeHost 参与select 语句的负载均衡,简单的说,当双
主双从模式(M1->S1,M2->S2,并且M1 与M2 互为主备),正常情况下,M2,S1,S2 都参与select 语句的负载均衡。
3. balance="2",所有读操作都随机的在writeHost、readhost 上分发。
4. balance="3",所有读请求随机的分发到wiriterHost 对应的readhost 执行,writerHost 不负担读压力,注意balance=3 只在1.4 及其以后版本有。
writeType 属性
负载均衡类型,目前的取值有2种:
1. writeType="0", 所有写操作发送到配置的第一个writeHost,第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties .
2. writeType="1",所有写操作都随机的发送到配置的writeHost,1.5 以后废弃不推荐。
dbType 属性
指定后端连接的数据库类型,目前支持二进制的mysql 协议,还有其他使用JDBC 连接的数据库。例如:mongodb、oracle、spark 等。
dbDriver 属性
指定连接后端数据库使用的Driver,目前可选的值有native 和JDBC。使用native 的话,因为这个值执行的是二进制的mysql 协议,所以可以使用mysql 和maridb。其他类型的数据库则需要使用JDBC 驱动来支持。
从1.6 版本开始支持postgresql 的native 原始协议。
如果使用JDBC 的话需要将符合JDBC 4 标准的驱动JAR 包放到MYCAT\lib 目录下,并检查驱动JAR 包中包括如下目录结构的文件:META-INF\services\java.sql.Driver。在这个文件内写上具体的Driver 类名,例如:
com.mysql.jdbc.Driver。
switchType 属性
-1 表示不自动切换
1 默认值,自动切换
2 基于MySQL 主从同步的状态决定是否切换
心跳语句为show slave status
3 基于MySQL galary cluster 的切换机制(适合集群)(1.4.1)
心跳语句为show status like ‘wsrep%’
slaveThreshold 属性
Mycat 心跳机制通过检测show slave status 中的"Seconds_Behind_Master", "Slave_IO_Running","Slave_SQL_Running" 三个字段来确定当前主从同步的状态以及Seconds_Behind_Master 主从复制时延,当Seconds_Behind_Master>slaveThreshold 时,读写分离筛选器会过滤掉此Slave 机器,防止读到很久之前的旧数据。
heartbeat 标签
这个标签内指明用于和后端数据库进行心跳检查的语句。例如,MYSQL 可以使用select user(),Oracle 可以使用select 1 from dual 等。
这个标签还有一个connectionInitSql 属性,主要是当使用Oracla 数据库时,需要执行的初始化SQL 语句就这个放到这里面来。例如:alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'
7.7.1 writeHost 标签、readHost 标签
这两个标签都指定后端数据库的相关配置给mycat,用于实例化后端连接池。唯一不同的是,writeHost 指定写实例、readHost 指定读实例,组着这些读写实例来满足系统的要求。
在一个dataHost 内可以定义多个writeHost 和readHost。但是,如果writeHost 指定的后端数据库宕机,那么这个writeHost 绑定的所有readHost 都将不可用。另一方面,由于这个writeHost 宕机系统会自动的检测到,并切换到备用的writeHost 上去。
这两个标签的属性相同
host 属性
用于标识不同实例,一般writeHost 我们使用*M1,readHost 我们用*S1。
url 属性
后端实例连接地址,如果是使用native 的dbDriver,则一般为address:port 这种形式。用JDBC 或其他的
dbDriver,则需要特殊指定。当使用JDBC 时则可以这么写:jdbc:mysql://localhost:3306/。
user 属性
后端存储实例需要的用户名字。
password 属性
后端存储实例需要的密码。
weight 属性
权重配置在readhost 中作为读节点的权重(1.4 以后)。
usingDecrypt 属性
是否对密码加密默认0 否如需要开启配置1,同时使用加密程序对密码加密,加密命令为:
执行mycat jar 程序(1.4.1 以后):
java -cp Mycat-server-1.4.1-dev.jar io.mycat.util.DecryptUtil 1:host:user:password
Mycat-server-1.4.1-dev.jar 为mycat download 下载目录的jar
1:host:user:password 中1 为db 端加密标志,host 为dataHost 的host 名称
server.xml
server.xml 几乎保存了所有mycat 需要的系统配置信息
user 标签
test
TESTDB
true
11111
主要用于定义登录mycat 的用户和权限。例如上面的例子中,我定义了一个用户,用户名为test、密码也为test,可访问的schema 也只有TESTDB 一个。
如果我在schema.xml 中定义了多个schema,那么这个用户是无法访问其他的schema。
嵌套的property 标签则是具体声明的属性值
Benchmark 属性
Benchmark:mycat 连接服务降级处理:
benchmark 基准, 当前端的整体connection 数达到基准值时, 对来自该账户的请求开始拒绝连接,0 或不设表示不限制例如1000
privileges 子节点
对用户的schema 及下级的table 进行精细化的DML 权限控制,privileges 节点中的check 属性是用于标识是否开启DML 权限检查, 默认false 标识不检查,当然privileges 节点不配置,等同check=false,
由于Mycat 一个用户的schemas 属性可配置多个schema ,所以privileges 的下级节点schema 节点同样可配置多个,对多库多表进行细粒度的DML 权限控制
system 标签
charset 属性
字符集设置。
processors 属性
这个属性主要用于指定系统可用的线程数,默认值为机器CPU 核心线程数。
processorBufferChunk 属性
这个属性指定每次分配Socket Direct Buffer 的大小,默认是4096 个字节。这个属性也影响buffer pool 的长度。如果一次性获取的数过大buffer 不够用经常出现警告,则可以适当调大。
processorExecutor 属性
这个属性主要用于指定NIOProcessor 上共享的businessExecutor 固定线程池大小。mycat 在需要处理一些异步逻辑的时候会把任务提交到这个线程池中。新版本中这个连接池的使用频率不是很大了,可以设置一个较小的值。
sequnceHandlerType 属性
指定使用Mycat 全局序列的类型。0 为本地文件方式,1 为数据库方式,2 为时间戳序列方式,3 为分布式ZK ID 生成器,4 为zk 递增id 生成。
从1.6 增加两种ZK 的全局ID 生成算法。
Mysql 连接相关属性
初始化mysql 前后端连接所涉及到的一些属性:
idleTimeout : 指定连接的空闲超时时间。某连接在发起空闲检查下,发现距离上次使用超过了空闲时间,那么这个连接会被回收,就是被直接的关闭掉。默认30 分钟,单位毫秒。
服务相关属性
这里介绍一个与服务相关的属性,主要会影响外部系统对mycat 的感知。
bindIp : mycat 服务监听的IP 地址,默认值为0.0.0.0。
serverPort : 定义mycat 的使用端口,默认值为8066。
managerPort : 定义mycat 的管理端口,默认值为9066。
fakeMySQLVersion
mycat 模拟的mysql 版本号,默认值为5.6 版本,如非特需,不要修改这个值,目前支持设置5.5,5.6 版本,其他版本可能会有问题。
此特性从1.6 版本开始支持。
全局表一致性检测
<property name="useGlobleTableCheck" >0property >
原理通过在全局表增加_MYCAT_OP_TIME 字段来进行一致性检测,类型为bigint,create 语句通过mycat执行会自动加上这个字段,其他情况请自己手工添加。
此特性从1.6 版本开始支持。
分布式事务开关
0
主要应用场景,主要为了控制是否允许跨库事务。
此特性从1.6 版本开始支持。
Off Heap for Mycat
此特性从1.6 版本开始支持。
1
1.使用非堆内存(Direct Memory)处理跨分片结果集的Merge/order by/group by/limit。
2.通过server.xml 中的useOffHeapForMerge 参数配置是否启用非堆内存处理跨分片结果集
3.Mycat 内存分层管理:
a.结果集处理内存;
b.系统预留内存;
c.网络处理内存共三块。
其中网络处理内存部分全部为Direct Memory,结果集内存分为Direct Memory 和HeapMemory。但目前仅使用Direct Memory。系统预留内存为On Heap Memory。
rule.xml
rule.xml 里面就定义了我们对表进行拆分所涉及到的规则定义。我们可以灵活的对表使用不同的分片算法,或者对表使用相同的算法但具体的参数不同。这个文件里面主要有tableRule 和function 这两个标签。在具体使用过程中可以按照需求添加tableRule 和function。
tableRule 标签
这个标签定义表规则。
定义的表规则,在schema.xml:
id
func1
name 属性指定唯一的名字,用于标识不同的表规则。
内嵌的rule 标签则指定对物理表中的哪一列进行拆分和使用什么路由算法。
columns 内指定要拆分的列名字。
algorithm 使用function 标签中的name 属性。连接表规则和具体路由算法。当然,多个表规则可以连接到同一个路由算法上。table 标签内使用。让逻辑表使用这个规则进行分片。
function 标签
partition-hash-int.txt
name 指定算法的名字。
class 制定路由算法具体的类名字。
property 为具体算法需要用到的一些属性。
Mycat分片规则
在数据切分处理中,特别是水平切分中,中间件最终要的两个处理过程就是数据的切分、数据的聚合。选择合适的切分规则,至关重要,因为它决定了后续数据聚合的难易程度,甚至可以避免跨库的数据聚合处理。
前面讲了数据切分中重要的几条原则,其中有几条是数据冗余,表分组(Table Group),这都是业务上规避跨库join 的很好的方式,但不是所有的业务场景都适合这样的规则,
主键分片vs 非主键分片
当没有任何字段可以作为分片字段的时候,主键分片就是唯一选择,其优点是按照主键的查询最快。
若有某个合适的业务字段比较合适作为分片字段,则建议采用此业务字段分片,选择分片字段的条件如下:
尽可能的比较均匀分布数据到各个节点上;
该业务字段是最频繁的或者最重要的查询条件。
常见的除了主键之外的其他可能分片字段有“订单创建时间”、“店铺类别”或“所在省”等。
选择合适分片的规则,尽量规避跨库Join 是一条最重要的原则,每种规则都有特定的场景,分析每种规则去选择合适的应用到项目中。
分片枚举
通过在配置文件中配置可能的枚举id,自己配置分片,本规则适用于特定的场景,比如有些业务需要按照省份或区县来做保存,而全国省份区县固定的,这类业务使用本条规则,配置如下:
partition-hash-int.txt
0
0
partition-hash-int.txt 配置:
10000=0
10010=1
DEFAULT_NODE=1
上面columns 标识将要分片的表字段,algorithm 分片函数,
其中分片函数配置中,mapFile 标识配置文件名称,type 默认值为0,0 表示Integer,非零表示String,
所有的节点配置都是从0 开始,及0 代表节点1
defaultNode 默认节点:小于0 表示不设置默认节点,大于等于0 表示设置默认节点 默认节点的作用:枚举分片时,如果碰到不识别的枚举值,就让它路由到默认节点, 如果不配置默认节点(defaultNode 值小于0 表示不配置默认节点),碰到 不识别的枚举值就会报错, can’t find datanode for sharding column:column_name val:ffffffff
固定分片hash 算法
本条规则类似于十进制的求模运算,区别在于是二进制的操作,是取id 的二进制低10 位,即id 二进制&1111111111。
2,1
256,512
配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数,partitionCount 分片个数列表,partitionLength 分片范围列表
分区长度:最大支持1024个 分区
约束:
count,length 两个数组的长度必须是一致的。
1024 = sum((count[i]*length[i])). count 和length 两个向量的点积恒等于1024
用法例子:
本例的分区策略:希望将数据水平分成3 份,前两份各占25%,第三份占50%。(故本例非均匀分区)
|<———————1024———————————>|
|<—-256—>|<—-256—>|<———-512————->|
| partition0 | partition1 | partition2 |
0 -------255,256------511,512----1023
如果需要平均分配设置:平均分为4 分片,partitionCount*partitionLength=1024
4
256
范围约定
此分片适用于,提前规划好分片字段某个范围属于哪个分片,
start <= range <= end.
range start-end ,data node index
K=1000,M=10000.
autopartition-long.txt
0
配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数,
rang-long 函数中mapFile 代表配置文件路径
defaultNode 超过范围后的默认节点。
所有的节点配置都是从0 开始,及0 代表节点1,此配置非常简单,即预先制定可能的id 范围到某个分片
0-500M=0
500M-1000M=1
1000M-1500M=2
或
0-10000000=0
10000001-20000000=1
取模
此规则为对分片字段求摸运算。
3
配置说明:
此种配置非常明确即根据id 进行十进制求模运算。
按日期(天)分片
此规则为按天分片。
yyyy-MM-dd
2014-01-01
2014-01-02
10
配置说明:
dateFormat :日期格式
sBeginDate :开始日期
sEndDate:结束日期
sPartionDay :分区天数,即默认从开始日期算起,分隔10 天一个分区
如果配置了sEndDate 则代表数据达到了这个日期的分片后后循环从开始分片插入。
取模范围约束
此种规则是取模运算与范围约束的结合。
256
2
partition-pattern.txt
partition-pattern.txt
# id partition range start-end ,data node index
1-32=0
33-64=1
65-96=2
97-128=3
129-160=4
161-192=5
193-224=6
225-256=7
0-0=7
配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数,patternValue 即求模基数,defaoultNode默认节点,默认节点,小于0表示不设置默认节点,大于等于0表示设置默认节点,如果超出配置的范围,则使用默认节点,mapFile 配置文件路径。
配置文件中,1-32 即代表id%256 后分布的范围,如果在1-32 则在分区1,其他类推,如果id 非数据,则会分配在defaoultNode 默认节点。
截取数字做hash 求模范围约束
此种规则类似于取模范围约束,此规则支持数据符号字母取模。
class="io.mycat.route.function.PartitionByPrefixPattern">
256
5
partition-pattern.txt
partition-pattern.txt
1-4=0
5-8=1
9-12=2
13-16=3
17-20=4
21-24=5
25-28=6
29-32=7
0-0=7
配置说明:
patternValue 即求模基数,prefixLength截取的位数
mapFile 配置文件路径
配置文件中,1-32 即代表id%256 后分布的范围,如果在1-32 则在分区1,其他类推
此种方式类似方式6 只不过采取的是将列种获取前prefixLength 位列所有ASCII 码的和进行求模。
截取数字hash 解析
此规则是截取字符串中的int 数值hash 分片。
512
2
0:2
配置说明:
函数中partitionLength 代表字符串hash 求模基数,
partitionCount 分区数,
hashSlice hash 预算位,即根据子字符串中int 值hash 运算
一致性hash
一致性hash 预算有效解决了分布式数据的扩容问题。
0
2
160
一致性哈希和虚拟一致性哈希
一致性哈希:
1. 首先求出服务器(节点)的哈希值,并将其配置到0~2的32次方的圆上。
2. 然后采用同样的方法求出存储数据的键的哈希值,并映射到相同的圆上。
3. 然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上。如果超过2的32次方仍然找不到服务器,就会保存到第一台服务器上。
一致性哈希算法对于节点的增减都只需重定位环空间中的一小部分数据,具有较好的容错性和可扩展性。
一致性哈希算法在服务节点太少时,容易因为节点分部不均匀而造成数据倾斜问题,此时必然造成大量数据集中到Node A上,而只有极少量会定位到Node B上。
为了解决这种数据倾斜问题,一致性哈希算法引入了虚拟节点机制,即对每一个服务节点计算多个哈希,每个计算结果位置都放置一个此服务节点,称为虚拟节点。具体做法可以在服务器ip或主机名的后面增加编号来实现。
例如,可以为每台服务器计算三个虚拟节点,于是可以分别计算 “Node A#1”、“Node A#2”、“Node A#3”、“Node B#1”、“Node B#2”、“Node B#3”的哈希值,于是形成六个虚拟节点:同时数据定位算法不变,只是多了一步虚拟节点到实际节点的映射,例如定位到“Node A#1”、“Node A#2”、“Node A#3”三个虚拟节点的数据均定位到Node A上。
这样就解决了服务节点少时数据倾斜的问题。在实际应用中,通常将虚拟节点数设置为32甚至更大,因此即使很少的服务节点也能做到相对均匀的数据分布。
按单月小时拆分
此规则是单月内按照小时拆分,最小粒度是小时,可以一天最多24 个分片,最少1 个分片,一个月完后下月从头开始循环。
每个月月尾,需要手工清理数据。
24
配置说明:
columns: 拆分字段,字符串类型(yyyymmddHH)
splitOneDay : 一天切分的分片数
范围求模分片
先进行范围分片计算出归属分片组,组内再根据组内分片数量求模。
class="io.mycat.route.function.PartitionByRangeMod">
partition-range-mod.txt
21
配置说明:
rang-mod 函数中mapFile 代表配置文件路径
defaultNode 超过范围后的默认节点顺序号,节点从0 开始。
partition-range-mod.txt
range start-end ,data node group size
以下配置一个范围代表一个分片组,=号后面的数字代表该分片组所拥有的分片的数量。
0-200M=5 //代表有5 个分片节点
200M1-400M=1
400M1-600M=4
600M1-800M=4
800M1-1000M=6
日期范围hash 分片
思想与范围求模一致,当由于日期在取模会有数据集中问题,所以改成hash 方法。
先根据日期分组,再根据时间hash 使得短期内数据分布的更均匀。
class="io.mycat.route.function.PartitionByRangeDateHash">
2014-01-01 00:00:00
3
yyyy-MM-dd HH:mm:ss
6
sPartionDay 代表多少天分一个分片
groupPartionSize 代表分片组的大小,在上述的例子中分片组共包含天数为6*3=18天
自然月分片
按月份列分区,每个自然月一个分片,格式between 操作解析的范例。
yyyy-MM-dd
2014-01-01
配置说明:
dateFormat : 日期字符串格式,默认为yyyy-MM-dd
sBeginDate : 开始日期,无默认值
sEndDate:结束日期,无默认值
节点从0 开始分片
应用指定
此规则是在运行阶段有应用自主决定路由到那个分片。
class="io.mycat.route.function.PartitionDirectBySubString">
0
2
8
0
配置说明:
此方法为直接根据字符子串(必须是数字)计算分区号(由应用传递参数,显式指定分区号)。
例如id=05-100000002在此配置中代表根据id 中从startIndex=0,开始,截取siz=2 位数字即05,05 就是获取的分区,如果没传
默认分配到defaultPartition
Mycat实战
我们用一个mini电商系统数据库表来实战一下。我们的现在mysql的架构是,两个服务器,A服务器上准备承载3个用户信息库,B服务器准备承载2个订单信息库,同时B服务器上启用了主从复制。
原始的库表说明如下:
区域表:
邮编表:
用户信息表:
订单表:
注,通过观察阿里等电商网站,可以发现,这些电商网站会把一个订单编号下只有一个商家的产品,所以我们也照此设计。
订单明细表:
现在业务发展,用户信息和订单信息都已经很庞大,我们需要进行分库分表了,怎么做呢?
我们已经确定了,我们要把用户信息和订单信息进行业务拆分,这样就进行了一次业务上的垂直拆分的分库。
业务拆库后,对用户信息和订单信息进入分库分表,其中最重要的一步,即分片字段(sharding column)的选取,分片字段选择的好坏将直接决定整个分库分表方案最终是否成功。而分片字段的选取跟业务强相关,选择分片字段的方法最主要分析你的API流量,优先考虑流量大的API,将流量比较大的API对应的SQL提取出来,将这些SQL共同的条件作为分片字段。
我们考察业务和用户信息表中的字段,用户登录属于高频和必须操作,表中牵涉到登录的字段有nicky_name和phone_name,那这两个字段我们考虑作为分片字段,而用户的id也是我们业务上经常要用的字段,也应该作为分片字段。现在有三个字段需要成为分区字段了,那么这种情况下应该怎么办呢?我们其实可以考虑将用户信息表进行拆表,nicky_name和phone_name统称为登录字段,用户登录后通过登录字段找到用户的id。所以用户信息表变为:
订单业务从业务角度来说,有三个column作为三个独立的sharding column,即:order本身的id,buyer_user_id,merchant_user_id。因为订单业务中买家和卖家的查询流量都比较大。而根据order_id进行分库分表,应该是根据order_id的查询也比较多。本次实战中,这个order_id我们不予处理,因为方法和buyer_user_id,merchant_user_id是一样的。
这里还有一点需要提及,多个sharding-column的分库分表是全量冗余还是只冗余关系索引表。
冗余全量的情况如下--每个sharding列对应的表的数据都是全量的,这样做的优点是不需要二次查询,性能更好,缺点是比较浪费存储空间。我们本次采用这种方式,那么表会变为:
注:采用冗余关系索引表分区,表结构可以这样设计,订单表保持不变,分区字段为order本身的id,新建两张表,分区字段分别为buyer_user_id,merchant_user_id,即
分区字段为merchant_user_id:
sharding column为buyer_user_id:
这样做的优点是节省空间,缺点是除了第一个sharding column的查询,其他sharding column的查询都需要二次查询:
而订单明细表和订单表是个典型的主从明细表,从Mycat的提供的表类型来说,属于ER表类型,为了分片后,让明细记录和订单记录落在同一个节点上,所以这个表也要有两个,但是表结构一样。
表结构确定后,那就是分区算法的选择了,对用户信息表因为是id分片,所以我们直接用id取模就行,而登录表的分区字段是字符串,所以我们选择截取一部分字符串做hash求模。订单表,我们选择算法“取模范围约束”。
至于post,因为用的很少,所以我们把它只放在一个节点上,而区域表完美的符合mycat中全局表的定义,所以区域表我们把它定义为全局表,那么mycat中配置文件就应该是这个样子:
Mycat架构剖析和实现分析
主体架构
Mycat在逻率持上由几个模块组成:通信协议、路由解析、结果集处理、数据库连接、监控等模块。
1.通信协议模块
通信协议模块承担底层的收发数据、线程回调处理工作,主要采用 Reactor、 proactor模式来提高效率。目前, Mycat通信模块默认釆用 Reactor模式,在协议层采用 MySQL协议。
2.路由解析模块
路由解析模块负责对传入的SL语句进行语法解析,解析从 MySQL协议中解析出来并进入该模块的SQL语句的条件、语句类型、携带的关键字等,对符合要求的SQL语句进行相关优化,最后根据这些路由计算单元进行路由计算。
3.结果集处理模块
结果集处理模块负责对跨分片的结果进行汇聚、排序、截取等。由于数据存储在不同的数据库中,所以对跨分片的数据需要进行汇聚。
4.数据库连接模块
数据库连接模块负责创建、管理、维护后端的连接池。为了诚少每次建立数据库连接的开销,数据库使用连接池机制对连接生命周期进行管理
5.监控管理模块
监控管理模块负责对 Mycat中的连接、内存等资源进行监控和管理。监控主要是通过管理命令实时地展现一些监控数据,例如连接数、缓存命中数等;管理则主要通过轮询事件来检测和释放不使用的资源。
6.SQL执行模块
SQL执行模块负责从连接池中获取相应的目标连接,对目标连接进行信息同步后,再根据路由解析的结果,把SQL语句分发到相应的节点执行。
总体执行流程
主要流程:由通信协议模块的读写事件通知发起。读写事件通知具体的回调代码进行这次读写事件的处理。管理模块的执行流程由定时器事件进行资源检查和资源释放时发起
由客户端发送过来的数据通过协议解析、路由解析等流程进入执行组件。通过执行组件把数据发送到通信协议模块,最终数据被写入目标数据库。
由后端数据库返回数据,通过协议解析后发送至回调模块。如果是涉及多节点的数据,则执行流程将会先进入结果集汇聚、排序等模块中,然后将处理后的数据通过通信协议模块返回到客户端。
路由
从原理上来看,可以把mycat 看成一个sql 转发器。mycat 接收到前端发来的sql,然后转发到后台的mysql 服务器上去执行。但是后面有很多台mysql 节点(如dn1,dn2,dn3),该转发到哪些节点呢?这就是路由解析该做的事情了。
路由能保证sql 转发到正确的节点。转发的范围是刚刚好,不多发也不少发。在选型上,mycat使用的是druidparser。
跨库join的实现
全局表
任何一个企业级的系统都会有很多基础信息表,它们的数据结构相对比较简单,类似于字典表,它们和业务表之间有关系,但是这种关系肯定不会是主从关系,大多数是一种属性关系,相当于配置信息,比如省份、城市、区域等。
当业务的数据量达到一定的规模,我们需要对业务表进行分片时,业务表和相关的基础信息之间的关系就变得非常麻烦,而这些基础信息表有如下一些特点
数据的变化不频繁
数据量的规模也比较小,在一般情况下为几万条记录,很少超过几十万条记录
鉴于这些特点, Mycat定义了一种特殊的表,叫作全局表。在全局表中进行插入操作时,每个节点同时并发插入和更新数据,而在读取数据的时候,因为任意节点的数据都是相同的,所以任意节点都可以读,这样在提升读性能的同时解决了跨节点Join的效率。
全局表的重要特性如下。
全局表的插入、更新、删除操作会实时地在所有节点同步执行,保持各个分片的数据的一致性
全局表的查询操作会从任意节点执行,因为所有节点的数据都一致全局表可以和任意表进行Join操作
将基础信息表和字典表定义成全局表,从业务上来看,业务表分片后,不会影响它们之间的Join操作,这是解决跨库Join的一种实现,通过全局表再加上ER关系的分片规则, Mycat可以满足大部分企业级的应用系统。
ER分片
数据库的ER关系模型是目前应用系统中经常使用到的, Mycat参考了 NewSQL领域的新秀 Foundation dB的设计思路。 Foundation DB创新性地提出了 Table Group的概念,子表的存储位置依赖于主表,并且在物理上紧邻存放,因此彻底解决了 Join的效率和性能问题,并根据这一思路,提出了基于E-R关系的数据分片策略,子表的记录与所关联的父表记录存放在同个数据分片上。
存在关联关系的父、子表在数据插入的过程中,子表会被 Mycat路由到与其相关的父表记录的节点上,从而使父、子表的Join査询可以下推到各个数据库节点完成,这是最高效的跨节点Join处理技术,也是 Mycat的首创,如图7-12所示。
Customer表采用了按范围分片的策略,每个范围内的 Customer在一个分片上, Customer和 Customer100分片在 host 1、host2上。从图7-12可以知道, Customer1的 Orderl和 Order2订单在host分片上, Customer100的Oder3和 Order100订单在host2分片上,所以 orders表的记录依赖父表进行分片,两个表的关联关系为 orders customer id= customer id。
按照这样的分片规则,host1分片上的 customer与 orders就可以进行局部的Join操作,在host2分片上也一样,就是在各自的分片上先做Join,然后在 Mycat内部合并两个节点的数据,这样就完成了跨分片的Join。试想一下,每个分片上 orders表有100万条,所以10个分片就有1亿条,基于ER映射的数据分片模式基本上解决了比较多的应用所面临的问题。
但是有很多业务存在多层ER关系,对于这种情况,其实有种非常简单的方法,就是用空间换时间的概念,简单地说就是多层E-R关系如第二、三层的E-R关系,通过增加冗余字段来解决这个问题。比如,在上面的例子中还有个 Orders的子表 Order items,只要这个表新增一个字段customer id就可以了,也就是把第二、三层的ER关系转化为第一层的ER关系进行分片。
ShareJoin 是Catlet 的一个实现,把解析出的SQL 分次执行,并存结果集,合并结果集。
汇聚和排序
把解析出的SQL 分次执行,并存结果集,合并结果集,如果有排序则是用的将结果集在mycat中进行了堆排序。
你可能感兴趣的:(mysql性能优化相关)
MySQL 管理:全面指南
wjs2024
开发语言
MySQL管理:全面指南引言MySQL是目前最流行的开源关系数据库管理系统之一,以其高性能、易用性和可靠性而闻名。本篇文章将深入探讨MySQL的管理,包括安装、配置、性能优化、安全性和备份恢复等方面,旨在为数据库管理员和开发者提供一份全面的管理指南。目录MySQL简介MySQL安装与配置MySQL性能优化MySQL安全性管理MySQL备份与恢复MySQL高可用与集群MySQL监控与维护MySQL常
MySQL性能优化:深入理解InnoDB的自适应哈希索引
rain1309
数据库 mysql 性能优化 哈希算法
前言MySQL的自适应哈希索引(AdaptiveHashIndex,简称AHI)是InnoDB存储引擎的一项关键特性,旨在提升查询性能和数据库的整体性能。自适应哈希索引通过动态调整哈希表的大小,使其“刚刚好”,从而优化查询效率。这种索引技术在特定场景下能够显著提升查询性能,是一种高效的索引优化技术。原理理念InnodB存储引擎会监控对表上各索引页的查询。如果观察到建立哈希索引可以带来速度提升,则建
MYSQL优化相关
peanut___
mysql优化3大方向:优化mysql所在服务器内核(运维完成)对mysql配置参数进行优化(my.cnf),此优化需要进行压力测试进行参数调整建表时的优化对sql语句的优化一、mysql参数优化mysql默认最大连接数为100,查看命令:showvariableslike'max_connections';(该机器最大连接数)设置最大连接数setglobalmax_connections=100
运维面试题(网络基础、系统管理)
王尼码
网络 运维 网络协议
目录网络基础类1、简述ISO/OSI七层模型的==分层与作用==相关-==TCP/IP四(五)层==模型与作用?2、简述TCP三次握手的过程相关-简述四次挥手的过程3、172.22.141.231/26,该IP位于哪个网段?该网段拥有多少可用IP地址?广播地址是什么?系统管理1、权限优化相关-用户user1,对/testdir目录有写和执行权限时,该目录下的只读文件file1是否可修改和删除?2、
MySQL 性能优化思路和工具
helloworld6379
笔记 面试 mysql 性能优化 数据库 索引 EXPLAIN
MySQL性能优化思路和工具一、优化思路作为架构师或者开发人员,说到数据库性能优化,你的思路是什么样的?或者具体一点,如果在面试的时候遇到这个问题:你会从哪些维度来优化数据库,你会怎么回答?我们说到性能调优,大部分时候想要实现的目标是让我们的查询更快。一个查询的动作又是由很多个环节组成的,每个环节都会消耗时间。我们要减少查询所消耗的时间,就要从每一个环节入手。二、连接——配置优化第一个环节是客户端
浅谈高性能缓存架构
风清扬鍀师傅
技术文章 架构 java
单纯依靠存储系统的性能提升不够的,典型的场景有:需要经过复杂运算后得出的数据,存储系统无能为力例如,一个论坛需要在首页展示当前有多少用户同时在线,如果使用MySQL来存储当前用户状态,则每次获取这个总数都要“count(*)”大量数据,这样的操作无论怎么优化MySQL,性能都不会太高。如果要实时展示用户同时在线数,则MySQL性能无法支撑。读多写少的数据,存储系统有心无力绝大部分在线业务都是读多写
MySQL性能调优篇(3)-缓存的优化与清理
俞兆鹏
MySQL学习指南 mysql
MySQL数据库缓存的优化与清理数据库缓存在MySQL中扮演着非常重要的角色,它可以显著提高数据库的性能和响应速度。在本篇博客中,我们将介绍如何优化和清理MySQL数据库的缓存,以进一步提高数据库的效率。优化缓存1.适当调整缓存大小MySQL数据库的缓存大小对性能有着直接的影响。通过修改以下两个参数,可以调整缓存的大小:innodb_buffer_pool_size:适用于InnoDB存储引擎,用
MySQL性能调优篇(4)-查询语句的优化与重构
俞兆鹏
MySQL学习指南 mysql
MySQL数据库查询语句的优化与重构MySQL是一种常用的关系型数据库管理系统,广泛应用于Web开发中。在实际应用中,对数据库查询语句的优化和重构是提高应用性能和响应速度的重要手段。本文将介绍一些常见的优化技巧和重构方法,帮助开发者提高数据库查询效率。优化索引索引是数据库中存储数据位置的数据结构,可以加快查询操作的速度。对于频繁查询的列,可以为其添加索引。常用的索引类型包括主键索引、唯一索引和普通
MySQL性能调优-(七)分区分表
努力的布布
MySQL mysql
分区表的应用场景1.表非常大以至于无法全部都放在内存中,或者只在表的最后部分有热点数据,其他均是历史数据2.分区表的数据更容易维护批量删除大量数据可以使用清除整个分区的方式对一个独立分区进行优化、检查、修复等操作3.分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备4.可以使用分区表来避免某些特殊的瓶颈innodb的单个索引的互斥访问ext3文件系统的inode锁竞争5.可以备份和
MySQL性能调优篇(5)-分区表的设计和使用
俞兆鹏
MySQL学习指南 mysql
数据库分区表是MySQL中一种高效的数据管理技术,能够帮助我们更好地进行数据存储和查询。在本文中,我们将介绍MySQL数据库分区表的设计和使用。什么是数据库分区表数据库分区表是将一个大表拆分成多个小表,每个小表称为一个分区。分区表在逻辑上仍然是一个完整的表,但在物理存储上被分成多个部分。分区表可以根据表中的某个列的值进行划分,比如根据日期、地区、用户ID等。这样可以将数据分散存储在不同的分区中,提
Redis大key有什么危害?如何排查和处理?
这个问题在面试中还是比较容易遇到的,尤其是在考察Redis性能优化相关知识点的时候。通常情况下,问了bigkey(大Key)还会继续问hotkey(热Key)。即使不准备面试也建议看看,实际开发中也能够用到(hotkey相关的内容会在下一篇文章中提到)。什么是bigkey?简单来说,如果一个key对应的value所占用的内存比较大,那这个key就可以看作是bigkey。具体多大才算大呢?有一个不是
如何在使用Texture2DArray的时候开启Mipmap效果
侑虎科技UWA
1)如何在使用Texture2DArray的时候开启Mipmap效果2)CharacterController移动碰撞问题3)一个关于Shader下坐标系转换的问题4)加载配置内存过大问题5)关于UnityWebRequest的手机端Timeout无效的问题这是第280篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。UWA问答
MySQL性能调优篇(1)-分析执行计划的方法
俞兆鹏
MySQL学习指南 mysql
MySQL是一种常用的关系型数据库管理系统,它的性能优化对于数据处理的效率和性能至关重要。在优化MySQL数据库的过程中,分析执行计划是一个重要的步骤。执行计划是查询优化器在执行SQL语句时生成的一种解析树或操作流程图,用于描述MySQL数据库系统按照哪种方式执行查询操作。本文将介绍如何使用MySQL的语法来分析执行计划,并提供详细的示例。在MySQL中,我们可以使用EXPLAIN关键字来分析执行
iOS 性能优化相关整理(待补充)
Aliv丶Zz
1.基础优化1.减少使用xib及storyboard(加载速度慢;导致APP启动时间比较耗时,因为在APP启动main()以前需要加载他们)2.懒加载可以节省内存资源,用到时才去加载所使用对象3.单例模式在项目开发过程中会用到很多重大开销对象(比如NSDateFormatter和NSCalendar),如我们在列表需要计算用户年龄的时候会经常用到NSDateFormatter,还有一些时间的格式化
如何去写一手好SQL?
码农小光
作者:编码砖家链接:https://www.cnblogs.com/xiaoyangjia/p/11267191.htmlMySQL性能数据表设计索引优化SQL优化其他数据库博主负责的项目主要采用阿里云数据库MySQL,最近频繁出现慢SQL告警,执行时间最长的竟然高达5分钟。导出日志后分析,主要原因竟然是没有命中索引和没有分页处理。其实这是非常低级的错误,我不禁后背一凉,团队成员的技术水平亟待提高
科普向 - 趣味的斐波那契数列
weixin_33970449
面试
1.从一道面试题开始每个程序员从第一次接触计算机编程语言到真正作为工程师进行项目开发,都一定都见过下面这道题目:很多个台阶,可以一次走一个台阶,也可以一次走两个台阶,那么走台阶时,有多少种可能?解法有很多种,最经典的当属递归解法,围绕此解法的核心思想正是大名鼎鼎的斐波那契数列。(递归解法虽然计算量很大,但算法优化相关内容不本是文讨论范围)。2.斐波那契是谁斐波那契(LeonardoFibonacc
《MySQL 简易速速上手小册》第7章:MySQL监控和日志分析(2024 最新版)
江帅帅
《MySQL 简易速速上手小册》 mysql 数据库 数据分析 数据挖掘 人工智能 python web3
文章目录7.1配置和使用MySQL监控工具7.1.1基础知识7.1.2重点案例:使用Python和Prometheus监控MySQL性能7.1.3拓展案例1:自动化MySQL慢查询日志分析7.1.4拓展案例2:实时警报系统7.2解读MySQL日志文件7.2.1基础知识7.2.2重点案例:使用Python分析慢查询日志7.2.3拓展案例1:实时监控错误日志7.2.4拓展案例2:优化查询通过分析通用查
如何动态使用烘焙出来的ReflectionProbe-0.exr信息
侑虎科技UWA
1)如何动态使用烘焙出来的ReflectionProbe-0.exr信息2)相机拉远后,SpriteRenderer图有明显的锐利3)Unity版本升级后Text的颜色修改无效4)Shader中UNITY_REVERSED_Z的含义这是第273篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。UWA问答社区:answer.uwa
2021最新MySQL性能优化问题
码农K
今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显。关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情。当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能。这里,我们不会讲过多的SQL语句的优化,而只是针对MySQL这一Web应用最多的数据库。希望下面的这些优化技巧对你有用。1.为查询缓存优
提速MySQL:数据库性能加速策略全解析
walkskyer
mysql 数据库 mysql
提速MySQL:数据库性能加速策略全解析引言理解MySQL性能指标监控和评估性能指标索引优化技巧索引优化实战案例查询优化实战查询优化案例分析存储引擎优化InnoDBvsMyISAM选择和优化存储引擎存储引擎优化实例配置调整与系统优化配置调整系统优化优化实例实战案例分析案例一:优化在线书店的库存查询案例二:改进客户订单历史查询性能引言在当今数据驱动的世界中,MySQL的优化已成为确保应用程序高效运行
MySQL性能分析
Noperx
一、MySQL常见瓶颈CPU:SQL中对大量数据进行比较、关联、排序、分组IO:实例内存满足不了缓存数据或排序等需要,导致产生大量物理IO。2查询执行效率低,扫描过多数据行。锁:不适宜的锁的设置,导致线程阻塞,性能下降。死锁,线程之间交叉调用资源,导致死锁,程序卡住。服务器硬件的性能瓶颈:top,free,iostat和vmstat来查看系统的性能状态二、Explain2.1、解释使用EXPLAI
数据库MySQL基本知识及面试总结——全新回归
尚墨1111
Java后端面试准备 mysql big data 数据库
文章目录数据库MySQL基本知识及面试总结1.基本内容1.1数据库三大范式是什么1.2一条sql语句在mysql中如何执行1.3MySQL性能瓶颈1.4数据库调优1.5说一说drop、delete与truncate的区别1.6基本语法1.6.1创建1.6.2逻辑运算符1.6.3通配符1.6.4聚合函数1.6.5过滤分组1.6.6笛卡尔积1.6.7连接查询1.6.8SQL注入2.存储引擎2.1Mys
看这一篇就够了,如何写一手好SQL?
AnyL8023
MySQL性能最大数据量抛开数据量和并发数,谈性能都是耍流氓。MySQL没有限制单表最大记录数,它取决于操作系统对文件大小的限制。看这一篇就够了,如何写一手好SQL?《阿里巴巴Java开发手册》提出单表行数超过500万行或者单表容量超过2GB,才推荐分库分表。性能由综合因素决定,抛开业务复杂度,影响程度依次是硬件配置、MySQL配置、数据表设计、索引优化。500万这个值仅供参考,并非铁律。曾经操作
MySQL全表扫描:性能杀手的隐患与优化策略
爱编程的鱼
MySQL 算法结构 mysql 数据库
MySQL全表扫描:性能杀手的隐患与优化策略MySQL数据库作为常用的关系型数据库管理系统之一,全表扫描问题一直困扰着开发者。本文将深入剖析MySQL全表扫描的原理、其对性能的严重影响,同时提供一系列优化策略,助您高效应对MySQL性能杀手。MySQL全表扫描的原理MySQL全表扫描是指数据库在执行查询操作时,需要逐行遍历表中的记录,进行过滤和匹配,直到找到满足查询条件的数据或扫描完整个表。全表扫
MySQL性能优化
tot_lbr
mysql 性能优化 数据库
MySQL性能优化1.索引优化索引在MySQL中扮演着关键角色,良好的索引设计可以显著提升查询效率。索引有多种类型,主要包括:B树索引:适用于全键值、范围查询,是最常见的索引类型。哈希索引:适用于等值查询,但不支持范围查询,对于内存表效果显著。全文索引:用于对文本的全文检索,主要用于MyISAM引擎。优化索引时需要注意:选择合适的数据类型:确保使用最适合存储数据的数据类型,减小索引大小,提高查询速
【MySQL性能优化】- MySQL结构与SQL执行过程
一个有梦有戏的人
MySQL mysql 性能优化 sql执行过程
MySQL结构与SQL执行过程生命不息,写作不止继续踏上学习之路,学之分享笔记总有一天我也能像各位大佬一样博客首页@怒放吧德德To记录领地分享学习心得,欢迎指正,大家一起学习成长!文章目录MySQL结构与SQL执行过程前言SQL执行结构连接器查询缓存分析器词法分析语法分析分析器的原理优化器执行器总结前言上阶段初步学习了索引与优化,以及对Explain的使用,接着来就来初识一下SQL执行的时候底层是
【MySQL性能优化】- 存储引擎及索引与优化
一个有梦有戏的人
MySQL mysql 性能优化 数据库 mysql索引 存储引擎
索引与优化生命不息,写作不止继续踏上学习之路,学之分享笔记总有一天我也能像各位大佬一样博客首页@怒放吧德德To记录领地分享学习心得,欢迎指正,大家一起学习成长!文章目录索引与优化前言存储引擎MyISAM存储引擎InnoDB存储引擎其他存储引擎InnoDB与MyISAM的区别索引底层原理什么是索引?索引的数据结构二叉树红黑树B-树B+树HashMySQL索引的底层存储聚簇索引与非聚簇索引MyISAM
【MySQL性能优化】- Explian用法与结果集详细分析
一个有梦有戏的人
MySQL mysql 性能优化 EXPLAIN SQL调优
Explain详细介绍生命不息,写作不止继续踏上学习之路,学之分享笔记总有一天我也能像各位大佬一样博客首页@怒放吧德德To记录领地分享学习心得,欢迎指正,大家一起学习成长!文章目录Explain详细介绍简介Explain使用数据准备Explain各列的解读1)、id2)、select_type3)、table4)、type5)、possible_keys6)、key7)、key_len8)、ref
【MySQL性能优化】- MySQL事务级别与锁机制
一个有梦有戏的人
MySQL sql mysql 性能优化 数据库
MySQL事务级别与锁机制生命不息,写作不止继续踏上学习之路,学之分享笔记总有一天我也能像各位大佬一样博客首页@怒放吧德德To记录领地分享学习心得,欢迎指正,大家一起学习成长!转发请携带作者信息@怒放吧德德@一个有梦有戏的人文章目录MySQL事务级别与锁机制简介事务及ACID并发事务带来的问题丢失修改(LostModify)或脏写脏读(Dirtyreads)不可重复读(Non-repeatable
PostgreSQL数据库的OS内存优化要点
DBAIOps社区
PG技术文章 数据库 postgresql dba 运维
为了更好的运行PG数据库,操作系统的内存必须做好优化。与PG优化相关的操作系统内存优化主要涉及几个方面:内存规划、NUMA设置、HUGEPAGE设置、VM参数优化、SWAP相关优化等。本文所说的方法不仅仅可以用于PG数据库优化,大多数配置对于其他数据库的优化也有一定的参考价值。要强调的一点是,对于绝大多数系统来说,过度的内存优化并不一定是必须的,只要保证足够的物理内存,就可以让PG数据库运行的十分
PHP如何实现二维数组排序?
IT独行者
二维数组 PHP 排序
二维数组在PHP开发中经常遇到,但是他的排序就不如一维数组那样用内置函数来的方便了,(一维数组排序可以参考本站另一篇文章【PHP中数组排序函数详解汇总】)。二维数组的排序需要我们自己写函数处理了,这里UncleToo给大家分享一个PHP二维数组排序的函数:
代码:
functionarray_sort($arr,$keys,$type='asc'){
$keysvalue= $new_arr
【Hadoop十七】HDFS HA配置
bit1129
hadoop
基于Zookeeper的HDFS HA配置主要涉及两个文件,core-site和hdfs-site.xml。
测试环境有三台
hadoop.master
hadoop.slave1
hadoop.slave2
hadoop.master包含的组件NameNode, JournalNode, Zookeeper,DFSZKFailoverController
由wsdl生成的java vo类不适合做普通java vo
darrenzhu
VO wsdl webservice rpc
开发java webservice项目时,如果我们通过SOAP协议来输入输出,我们会利用工具从wsdl文件生成webservice的client端类,但是这里面生成的java data model类却不适合做为项目中的普通java vo类来使用,当然有一中情况例外,如果这个自动生成的类里面的properties都是基本数据类型,就没问题,但是如果有集合类,就不行。原因如下:
1)使用了集合如Li
JAVA海量数据处理之二(BitMap)
周凡杨
java 算法 bitmap bitset 数据
路漫漫其修远兮,吾将上下而求索。想要更快,就要深入挖掘 JAVA 基础的数据结构,从来分析出所编写的 JAVA 代码为什么把内存耗尽,思考有什么办法可以节省内存呢? 啊哈!算法。这里采用了 BitMap 思想。
首先来看一个实验:
指定 VM 参数大小: -Xms256m -Xmx540m
java类型与数据库类型
g21121
java
很多时候我们用hibernate的时候往往并不是十分关心数据库类型和java类型的对应关心,因为大多数hbm文件是自动生成的,但有些时候诸如:数据库设计、没有生成工具、使用原始JDBC、使用mybatis(ibatIS)等等情况,就会手动的去对应数据库与java的数据类型关心,当然比较简单的数据类型即使配置错了也会很快发现问题,但有些数据类型却并不是十分常见,这就给程序员带来了很多麻烦。
&nb
Linux命令
510888780
linux命令
系统信息
arch 显示机器的处理器架构(1)
uname -m 显示机器的处理器架构(2)
uname -r 显示正在使用的内核版本
dmidecode -q 显示硬件系统部件 - (SMBIOS / DMI)
hdparm -i /dev/hda 罗列一个磁盘的架构特性
hdparm -tT /dev/sda 在磁盘上执行测试性读取操作
cat /proc/cpuinfo 显示C
java常用JVM参数
墙头上一根草
java jvm参数
-Xms:初始堆大小,默认为物理内存的1/64(<1GB);默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制
-Xmx:最大堆大小,默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制
-Xmn:新生代的内存空间大小,注意:此处的大小是(eden+ 2
我的spring学习笔记9-Spring使用工厂方法实例化Bean的注意点
aijuans
Spring 3
方法一:
<bean id="musicBox" class="onlyfun.caterpillar.factory.MusicBoxFactory"
factory-method="createMusicBoxStatic"></bean>
方法二:
mysql查询性能优化之二
annan211
UNION mysql 查询优化 索引优化
1 union的限制
有时mysql无法将限制条件从外层下推到内层,这使得原本能够限制部分返回结果的条件无法应用到内层
查询的优化上。
如果希望union的各个子句能够根据limit只取部分结果集,或者希望能够先排好序在
合并结果集的话,就需要在union的各个子句中分别使用这些子句。
例如 想将两个子查询结果联合起来,然后再取前20条记录,那么mys
数据的备份与恢复
百合不是茶
oracle sql 数据恢复 数据备份
数据的备份与恢复的方式有: 表,方案 ,数据库;
数据的备份:
导出到的常见命令;
参数 说明
USERID 确定执行导出实用程序的用户名和口令
BUFFER 确定导出数据时所使用的缓冲区大小,其大小用字节表示
FILE 指定导出的二进制文
线程组
bijian1013
java 多线程 thread java多线程 线程组
有些程序包含了相当数量的线程。这时,如果按照线程的功能将他们分成不同的类别将很有用。
线程组可以用来同时对一组线程进行操作。
创建线程组:ThreadGroup g = new ThreadGroup(groupName);
&nbs
top命令找到占用CPU最高的java线程
bijian1013
java linux top
上次分析系统中占用CPU高的问题,得到一些使用Java自身调试工具的经验,与大家分享。 (1)使用top命令找出占用cpu最高的JAVA进程PID:28174 (2)如下命令找出占用cpu最高的线程
top -Hp 28174 -d 1 -n 1
32694 root 20 0 3249m 2.0g 11m S 2 6.4 3:31.12 java
【持久化框架MyBatis3四】MyBatis3一对一关联查询
bit1129
Mybatis3
当两个实体具有1对1的对应关系时,可以使用One-To-One的进行映射关联查询
One-To-One示例数据
以学生表Student和地址信息表为例,每个学生都有都有1个唯一的地址(现实中,这种对应关系是不合适的,因为人和地址是多对一的关系),这里只是演示目的
学生表
CREATE TABLE STUDENTS
(
C/C++图片或文件的读写
bitcarter
写图片
先看代码:
/*strTmpResult是文件或图片字符串
* filePath文件需要写入的地址或路径
*/
int writeFile(std::string &strTmpResult,std::string &filePath)
{
int i,len = strTmpResult.length();
unsigned cha
nginx自定义指定加载配置
ronin47
进入 /usr/local/nginx/conf/include 目录,创建 nginx.node.conf 文件,在里面输入如下代码:
upstream nodejs {
server 127.0.0.1:3000;
#server 127.0.0.1:3001;
keepalive 64;
}
server {
liste
java-71-数值的整数次方.实现函数double Power(double base, int exponent),求base的exponent次方
bylijinnan
double
public class Power {
/**
*Q71-数值的整数次方
*实现函数double Power(double base, int exponent),求base的exponent次方。不需要考虑溢出。
*/
private static boolean InvalidInput=false;
public static void main(
Android四大组件的理解
Cb123456
android 四大组件的理解
分享一下,今天在Android开发文档-开发者指南中看到的:
App components are the essential building blocks of an Android
[宇宙与计算]涡旋场计算与拓扑分析
comsci
计算
怎么阐述我这个理论呢? 。。。。。。。。。
首先: 宇宙是一个非线性的拓扑结构与涡旋轨道时空的统一体。。。。
我们要在宇宙中寻找到一个适合人类居住的行星,时间非常重要,早一个刻度和晚一个刻度,这颗行星的
同一个Tomcat不同Web应用之间共享会话Session
cwqcwqmax9
session
实现两个WEB之间通过session 共享数据
查看tomcat 关于 HTTP Connector 中有个emptySessionPath 其解释如下:
If set to true, all paths for session cookies will be set to /. This can be useful for portlet specification impleme
springmvc Spring3 MVC,ajax,乱码
dashuaifu
spring jquery mvc Ajax
springmvc Spring3 MVC @ResponseBody返回,jquery ajax调用中文乱码问题解决
Spring3.0 MVC @ResponseBody 的作用是把返回值直接写到HTTP response body里。具体实现AnnotationMethodHandlerAdapter类handleResponseBody方法,具体实
搭建WAMP环境
dcj3sjt126com
wamp
这里先解释一下WAMP是什么意思。W:windows,A:Apache,M:MYSQL,P:PHP。也就是说本文说明的是在windows系统下搭建以apache做服务器、MYSQL为数据库的PHP开发环境。
工欲善其事,必须先利其器。因为笔者的系统是WinXP,所以下文指的系统均为此系统。笔者所使用的Apache版本为apache_2.2.11-
yii2 使用raw http request
dcj3sjt126com
http
Parses a raw HTTP request using yii\helpers\Json::decode()
To enable parsing for JSON requests you can configure yii\web\Request::$parsers using this class:
'request' =&g
Quartz-1.8.6 理论部分
eksliang
quartz
转载请出自出处:http://eksliang.iteye.com/blog/2207691 一.概述
基于Quartz-1.8.6进行学习,因为Quartz2.0以后的API发生的非常大的变化,统一采用了build模式进行构建;
什么是quartz?
答:简单的说他是一个开源的java作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。并且还能和Sp
什么是POJO?
gupeng_ie
java POJO 框架 Hibernate
POJO--Plain Old Java Objects(简单的java对象)
POJO是一个简单的、正规Java对象,它不包含业务逻辑处理或持久化逻辑等,也不是JavaBean、EntityBean等,不具有任何特殊角色和不继承或不实现任何其它Java框架的类或接口。
POJO对象有时也被称为Data对象,大量应用于表现现实中的对象。如果项目中使用了Hiber
jQuery网站顶部定时折叠广告
ini
JavaScript html jquery Web css
效果体验:http://hovertree.com/texiao/jquery/4.htmHTML文件代码:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>网页顶部定时收起广告jQuery特效 - HoverTree<
Spring boot内嵌的tomcat启动失败
kane_xie
spring boot
根据这篇guide创建了一个简单的spring boot应用,能运行且成功的访问。但移植到现有项目(基于hbase)中的时候,却报出以下错误:
SEVERE: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.Lif
leetcode: sort list
michelle_0916
Algorithm linked list sort
Sort a linked list in O(n log n) time using constant space complexity.
====analysis=======
mergeSort for singly-linked list
====code======= /**
* Definition for sin
nginx的安装与配置,中途遇到问题的解决
qifeifei
nginx
我使用的是ubuntu13.04系统,在安装nginx的时候遇到如下几个问题,然后找思路解决的,nginx 的下载与安装
wget http://nginx.org/download/nginx-1.0.11.tar.gz
tar zxvf nginx-1.0.11.tar.gz
./configure
make
make install
安装的时候出现
用枚举来处理java自定义异常
tcrct
java enum exception
在系统开发过程中,总少不免要自己处理一些异常信息,然后将异常信息变成友好的提示返回到客户端的这样一个过程,之前都是new一个自定义的异常,当然这个所谓的自定义异常也是继承RuntimeException的,但这样往往会造成异常信息说明不一致的情况,所以就想到了用枚举来解决的办法。
1,先创建一个接口,里面有两个方法,一个是getCode, 一个是getMessage
public
erlang supervisor分析
wudixiaotie
erlang
当我们给supervisor指定需要创建的子进程的时候,会指定M,F,A,如果是simple_one_for_one的策略的话,启动子进程的方式是supervisor:start_child(SupName, OtherArgs),这种方式可以根据调用者的需求传不同的参数给需要启动的子进程的方法。和最初的参数合并成一个数组,A ++ OtherArgs。那么这个时候就有个问题了,既然参数不一致,那