搜索
首页数据库mysql教程分享下去年底写的mysql分库分表中间件heisenberg_MySQL

目前维护在github上了,googlecode稳定性太差

https://github.com/brucexx/heisenberg

其优点: 分库分表与应用脱离,分库表如同使用单库表一样
减少db 连接数压力 
热重启配置
可水平扩容
遵守Mysql原生协议
无语言限制,mysqlclient,c,java等都可以使用
Heisenberg服务器通过管理命令可以查看,如连接数,线程池,结点等,并可以调整
采用velocity的分库分表脚本进行自定义分库表,相当的灵活

 

之前在组里有做过简单的分享,这段时间稍微轻松了点,先分享出来,看有没有更好的idea在这块有所提升

 

 下面开始介绍heisenberg

 

1.heisenberg总体架构

      首先这块架构:

      

      

 

应用对于heisenberg集群来说就是mysql客户端,

而heisenberg也是集成了mysql的原生协议,所以对于应用来说,就相当于单库单表的数据源

无论是mysql客户端,c,jdbc驱动等都可以访问heisenberg服务器,由服务器把分库分表的工作给做掉了

 

访问heisenberg集群可以通过像lvs,F5等负载软件/设备解决,

其实一台heisenberg的性能是相当的赞了,我压力到2320TPS load 都还只有0.1-0.3左右(CPU 8core,16G),由于找不到mysql物理机器了,只得做罢

 

服务端内部结构:


 

其中FrontConnectionFactory为面向应用的连接管理,ManagerConnectionFactory为面向heisenberg服务器内部管理的一些连接管理,比如更改配置后热重启,关闭 某个连接等功能

mysql协议贯穿于应用程序与mysql服务器,最终解析为相关的mysql数据包, 授权包,注册包等

 

当heisenberg服务器接收到SQL语句后,通过AST语法解析 解析成 DML,DCL,DDL类型以及相关列名的值等等,然后通过ServerRouter这一层,经过分库分表的切分,最终将切分好的语句放入对应数据结点进行执行

 

分库分表的切分,为了满足各种通用性灵活性,使用了velocity和groovy 2种语法来支持,其中groovy是初始化表和库和映射关系的,只在加载时初始化一次;而velocity是用来渲染对应的分库和分表规则的。

 

OK,知道了原理,那么开始说明如何使用分库分表吧

 

2.heisenberg开发

Maven +JDK 部署好

代码从 https://github.com/brucexx/heisenberg

 

下载到本地后,

Mvn package 之

 

在本地target里会生成一个heisenberg-server-1.0.0.zip 文件

 

解压之 unzip  heisenberg-server-1.0.0.zip  

进入conf目录

有下面几个目录 

     conf

      ---log4j.xml

      ---rule.xml

      ---schema.xml

      ---server.xml

log4j.xml就不介绍了

  sql_route.log就是分库表切分的时间

  sql_execute.log 为sql总执行时间

 

server.xml 

    "serverPort">8166

    "managerPort">8266

    "initExecutor">16

    "timerExecutor">4

    "managerExecutor">4

    "processors">4

    "processorHandler">8

    "processorExecutor">8

    "clusterHeartbeatUser">_HEARTBEAT_USER_

    "clusterHeartbeatPass">_HEARTBEAT_PASS_

 

 

serverPort为服务端口,即对上层应用的端口

managerPort为管理端口,即管理的监听端口,用于操作服务器一些配置等

initExecutor 为初始化的线程个数

timerExecutor 心跳执行线程个数

managerExecutor管理执行线程个数

processors应用接收处理器核数

processorHandler 应用接收处理类个数

processorExecutor 应用接收处理线程个数

 

clusterHeartbeatUserclusterHeartbeatPass 不必改,用于集群的认证方式使用

 

 "brucexx">

    "password">st0078

    "schemas">trans_shard

 

Brucexx为自定义应用用户名,st0078为自定义应用密码

Schemas为自定义schema,具体见schema.xml中,

 

这里的schemas可为多个,以逗号分隔

 

白名单限制:

 

  

   

      test

   

 

 

                

schema.xml配置

mysql数据源

 

    "transDS" type="mysql">

        "location">

            10.58.49.14:8701/db$0-9

   

        "user">root

        "password">st0078

        "sqlMode">STRICT_TRANS_TABLES

   

 

这里指定的mysql的数据源,后面$0-9是一种自定义的缩略写法

也可以在property里面定义多个location,比如:

"location">

            10.58.49.14:8701/db0

10.58.49.14:8701/db1

10.58.49.14:8701/db2

   

 

 

 

效果是一样的

 

Shard结点配置

Shard结点相当于一个逻辑结点,提供给外部相关的schema,对应于数据源有

主/备/灾,

"transDN">

        "dataSource">

           

            transDS$0-9

           

            transSlaveDS$0-9

           

            transSlaveDS$0-9

           

           

       

        "rwRule">

        "poolSize">256

        "heartbeatSQL">select user()

   

 

属性dataSource 第一个是主库,第二个备库,第三个灾库,需要多少配置多少个

 

读写分离规则rwRule,m和s代表读取的比例,表示主库读取为0,从库读取1,这样直接读写分离,如果是1:1的话相当读取各1:1的比例

 

池大小poolSize为到mysqlDB的连接数和心跳sql heartbeatSQL,无特殊需求保持不变

 

Schema配置

"trans_shard">

 

       

"trans_online, trans_content, trans_tb " dataNode="transDN$0-9"rule="rule1" />

   

 trans_shard 提供的schema,对应于server.xml中的名字

下面会有多个需要分库的表,

"trans_online" dataNode="transDN$0-9" rule="rule1" />

这里必须要把需要分库分表的内容写出来,当然,如果不分库表也是可以的

 

”tbxxx" dataNode="transDN0" ruleRequired=”false”/

 

rule.xml 

分库分表规则配置,其中columns,dbRuleList,tbRuleList里面的列名要保持大写

 

首先先上一个整体配置

    "rule1">

        TRANS_ID

   

           

            #set($end=$TRANS_ID.length() - 1)##

            $stringUtil.substring($TRANS_ID,$start,$end)]]>

           

       

       

           

             $stringUtil.substring($TRANS_ID,$start)]]>

       

       

       

               

                        def map = [:];

                        for (int i=0; i

                           def list = [];

                            for (int j=0; j

                                list.add(i+""+j);

                            }

                             map.put(i,list);

                        };

                        return map;

                ]]>

       

   

 

其中dbRuleList 为分库规则

 

           

            #set($end=$TRANS_ID.length() - 1)##

            $stringUtil.substring($TRANS_ID,$start,$end)]]>

           

       

 分库规则dbRuleList可以有多个dbRule,当第一个不满足时,可以用第二个,当然这个效率不好,如果有规则区分,尽量再写一个rule,

dbRule 最后的结果是表的前缀

比如分库分表 库名为db0-db9,那么这个dbRule渲染时

 

取到TRANS_ID 这个为后,在脚本里计算出取倒数第2位为库后缀

比如上图的分库为



 

分表规则配置

           

             $stringUtil.substring($TRANS_ID,$start)]]>

       

这个和上面分库一样了,以倒数1,2位为库的后缀

如下图:



 

 

 有个潜规则就是

需要保证全局的表名不能重复

比如db0有个trans_tb00,db1就不能有叫trans_tb00的表

 

表初始化

       

       

               

                        def map = [:];

                        for (int i=0; i

                           def list = [];

                            for (int j=0; j

                                list.add(i+""+j);

                            }

                             map.put(i,list);

                        };

                        return map;

                ]]>

       

 

需要初始化个表,其中key为db的下标索引,比如db0 的下标为0,

list为每个库里的表后缀名

 

 

目录是为了初始化定义这些库表

 

如何使用呢?

通过命令行


 

这里就不用讲了,wms_shard就是在server.xml里面配置的逻辑分库分表的数据源schema,应用只要访问这个就好了



 

show tables;也可以看到自己的一些表信息



 

ok.

 

mysql> select * from t_user_id_map;

+-----------+---------------------------+-----------+------------+---------------------+---------------------+

| F_uid     | F_uname                   | F_enabled | F_user_id  | F_create_time       | F_modify_time       |

+-----------+---------------------------+-----------+------------+---------------------+---------------------+

| 105001050 | @8230762802717b6a723fe9cd |         1 | 1287824017 | 2014-03-10 15:38:44 | 2014-03-10 15:38:44 |

|     62000 |                           |         1 |  533885000 | 2014-03-26 23:02:31 | 2014-03-26 23:02:31 |

|     86000 |                           |         1 |  237406000 | 2014-03-27 01:04:23 | 2014-03-27 01:04:23 |

|     96000 |                           |         1 |  767684000 | 2014-03-27 00:30:32 | 2014-03-27 00:30:32 |

|    130000 |                           |         1 |  506552000 | 2014-03-27 15:57:31 | 2014-03-27 15:57:31 |

|    149000 |                           |         1 |  868483000 | 2014-03-27 15:50:09 | 2014-03-27 15:50:09 |

|    179000 |                           |         1 |  245626000 | 2014-03-26 21:33:46 | 2014-03-26 21:33:46 |

当没有指定分库分表规则时,是进行的全表扫描,当然我们可以通过学习

mysql> explain select * from t_user_id_map;

+-----------+-----------------------------------

| DATA_NODE | SQL

+-----------+-----------------------------------

| wmsDN[0]  |  select * from t_user_id_map_00_0

| wmsDN[0]  |  select * from t_user_id_map_00_1

| wmsDN[0]  |  select * from t_user_id_map_00_2

| wmsDN[0]  |  select * from t_user_id_map_00_3

| wmsDN[0]  |  select * from t_user_id_map_00_4

| wmsDN[0]  |  select * from t_user_id_map_00_5

| wmsDN[0]  |  select * from t_user_id_map_00_6

| wmsDN[0]  |  select * from t_user_id_map_00_7

| wmsDN[0]  |  select * from t_user_id_map_00_8

| wmsDN[0]  |  select * from t_user_id_map_00_9

| wmsDN[1]  |  select * from t_user_id_map_01_0

| wmsDN[1]  |  select * from t_user_id_map_01_1

| wmsDN[1]  |  select * from t_user_id_map_01_2

| wmsDN[1]  |  select * from t_user_id_map_01_3

| wmsDN[1]  |  select * from t_user_id_map_01_4

| wmsDN[1]  |  select * from t_user_id_map_01_5

| wmsDN[1]  |  select * from t_user_id_map_01_6

| wmsDN[1]  |  select * from t_user_id_map_01_7

| wmsDN[1]  |  select * from t_user_id_map_01_8

| wmsDN[1]  |  select * from t_user_id_map_01_9

| wmsDN[2]  |  select * from t_user_id_map_02_0

....

这边表很多,其中dataNode是我们里面对应的结点

 

mysql> select * from t_user_id_map where f_uid=196606999;

+-----------+---------+-----------+-----------+---------------------+---------------------+

| F_uid     | F_uname | F_enabled | F_user_id | F_create_time       | F_modify_time       |

+-----------+---------+-----------+-----------+---------------------+---------------------+

| 196606999 |         |         1 | 749331999 | 2014-04-04 14:46:58 | 2014-04-04 14:46:58 |

+-----------+---------+-----------+-----------+---------------------+---------------------+

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
如何使用Alter Table语句在MySQL中更改表?如何使用Alter Table语句在MySQL中更改表?Mar 19, 2025 pm 03:51 PM

本文讨论了使用MySQL的Alter Table语句修改表,包括添加/删除列,重命名表/列以及更改列数据类型。

如何为MySQL连接配置SSL/TLS加密?如何为MySQL连接配置SSL/TLS加密?Mar 18, 2025 pm 12:01 PM

文章讨论了为MySQL配置SSL/TLS加密,包括证书生成和验证。主要问题是使用自签名证书的安全含义。[角色计数:159]

您如何处理MySQL中的大型数据集?您如何处理MySQL中的大型数据集?Mar 21, 2025 pm 12:15 PM

文章讨论了处理MySQL中大型数据集的策略,包括分区,碎片,索引和查询优化。

哪些流行的MySQL GUI工具(例如MySQL Workbench,PhpMyAdmin)是什么?哪些流行的MySQL GUI工具(例如MySQL Workbench,PhpMyAdmin)是什么?Mar 21, 2025 pm 06:28 PM

文章讨论了流行的MySQL GUI工具,例如MySQL Workbench和PhpMyAdmin,比较了它们对初学者和高级用户的功能和适合性。[159个字符]

如何使用Drop Table语句将表放入MySQL中?如何使用Drop Table语句将表放入MySQL中?Mar 19, 2025 pm 03:52 PM

本文讨论了使用Drop Table语句在MySQL中放下表,并强调了预防措施和风险。它强调,没有备份,该动作是不可逆转的,详细介绍了恢复方法和潜在的生产环境危害。

如何在JSON列上创建索引?如何在JSON列上创建索引?Mar 21, 2025 pm 12:13 PM

本文讨论了在PostgreSQL,MySQL和MongoDB等各个数据库中的JSON列上创建索引,以增强查询性能。它解释了索引特定的JSON路径的语法和好处,并列出了支持的数据库系统。

您如何用外国钥匙代表关系?您如何用外国钥匙代表关系?Mar 19, 2025 pm 03:48 PM

文章讨论了使用外国密钥来代表数据库中的关系,重点是最佳实践,数据完整性和避免的常见陷阱。

如何保护MySQL免受常见漏洞(SQL注入,蛮力攻击)?如何保护MySQL免受常见漏洞(SQL注入,蛮力攻击)?Mar 18, 2025 pm 12:00 PM

文章讨论了使用准备好的语句,输入验证和强密码策略确保针对SQL注入和蛮力攻击的MySQL。(159个字符)

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。