目录
1.heisenberg总体架构
2.heisenberg开发
mysql数据源
Shard结点配置
Schema配置
rule.xml 
分表规则配置
表初始化
首页 数据库 mysql教程 分享下去年底写的mysql分库分表中间件heisenberg_MySQL

分享下去年底写的mysql分库分表中间件heisenberg_MySQL

Jun 01, 2016 pm 01:10 PM

目前维护在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

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1666
14
CakePHP 教程
1425
52
Laravel 教程
1327
25
PHP教程
1273
29
C# 教程
1252
24
MySQL的角色:Web应用程序中的数据库 MySQL的角色:Web应用程序中的数据库 Apr 17, 2025 am 12:23 AM

MySQL在Web应用中的主要作用是存储和管理数据。1.MySQL高效处理用户信息、产品目录和交易记录等数据。2.通过SQL查询,开发者能从数据库提取信息生成动态内容。3.MySQL基于客户端-服务器模型工作,确保查询速度可接受。

说明InnoDB重做日志和撤消日志的作用。 说明InnoDB重做日志和撤消日志的作用。 Apr 15, 2025 am 12:16 AM

InnoDB使用redologs和undologs确保数据一致性和可靠性。1.redologs记录数据页修改,确保崩溃恢复和事务持久性。2.undologs记录数据原始值,支持事务回滚和MVCC。

MySQL:世界上最受欢迎的数据库的简介 MySQL:世界上最受欢迎的数据库的简介 Apr 12, 2025 am 12:18 AM

MySQL是一种开源的关系型数据库管理系统,主要用于快速、可靠地存储和检索数据。其工作原理包括客户端请求、查询解析、执行查询和返回结果。使用示例包括创建表、插入和查询数据,以及高级功能如JOIN操作。常见错误涉及SQL语法、数据类型和权限问题,优化建议包括使用索引、优化查询和分表分区。

MySQL的位置:数据库和编程 MySQL的位置:数据库和编程 Apr 13, 2025 am 12:18 AM

MySQL在数据库和编程中的地位非常重要,它是一个开源的关系型数据库管理系统,广泛应用于各种应用场景。1)MySQL提供高效的数据存储、组织和检索功能,支持Web、移动和企业级系统。2)它使用客户端-服务器架构,支持多种存储引擎和索引优化。3)基本用法包括创建表和插入数据,高级用法涉及多表JOIN和复杂查询。4)常见问题如SQL语法错误和性能问题可以通过EXPLAIN命令和慢查询日志调试。5)性能优化方法包括合理使用索引、优化查询和使用缓存,最佳实践包括使用事务和PreparedStatemen

为什么要使用mysql?利益和优势 为什么要使用mysql?利益和优势 Apr 12, 2025 am 12:17 AM

选择MySQL的原因是其性能、可靠性、易用性和社区支持。1.MySQL提供高效的数据存储和检索功能,支持多种数据类型和高级查询操作。2.采用客户端-服务器架构和多种存储引擎,支持事务和查询优化。3.易于使用,支持多种操作系统和编程语言。4.拥有强大的社区支持,提供丰富的资源和解决方案。

MySQL与其他编程语言:一种比较 MySQL与其他编程语言:一种比较 Apr 19, 2025 am 12:22 AM

MySQL与其他编程语言相比,主要用于存储和管理数据,而其他语言如Python、Java、C 则用于逻辑处理和应用开发。 MySQL以其高性能、可扩展性和跨平台支持着称,适合数据管理需求,而其他语言在各自领域如数据分析、企业应用和系统编程中各有优势。

MySQL:从小型企业到大型企业 MySQL:从小型企业到大型企业 Apr 13, 2025 am 12:17 AM

MySQL适合小型和大型企业。1)小型企业可使用MySQL进行基本数据管理,如存储客户信息。2)大型企业可利用MySQL处理海量数据和复杂业务逻辑,优化查询性能和事务处理。

MySQL索引基数如何影响查询性能? MySQL索引基数如何影响查询性能? Apr 14, 2025 am 12:18 AM

MySQL索引基数对查询性能有显着影响:1.高基数索引能更有效地缩小数据范围,提高查询效率;2.低基数索引可能导致全表扫描,降低查询性能;3.在联合索引中,应将高基数列放在前面以优化查询。

See all articles