数据库中间件Mycat

文章目录

      • Mycat中的概念
      • 应用场景
      • 角色
        • server.xml
        • schema.xml
        • rule.xml
        • sequence_db_conf.properties
      • 连接mycat
      • 自定义mycat 路由实现动态扩容
        • 算法实现
        • 程序-数据查询
        • 程序-数据更新
        • 程序-数据删除

Mycat中的概念

介于数据库与应用之间,进行数据处理与交互的中间服务

应用场景

1.单纯的读写分离,此时配置最为简单,支持读写分离,主从切换
2.分表分库,对于超过1000万的表进行分片,最大支持1000亿的单表分片
3.多租户应用,每个应用一个库,但应用程序只连接Mycat,从而不改造程序本身,实现多租户化
4.报表系统,借助于Mycat的分表能力,处理大规模报表的统计
5.替代Hbase,分析大数据
6.作为海量数据实时查询的一种简单有效方案,比如100亿条频繁查询的记录需要在3秒内查询出来结果,除了基于主键的查
询,还可能存在范围查询或其他属性查询,此时Mycat可能是最简单有效的选择
数据库中间件Mycat_第1张图片

角色

数据节点: DataNode:存储数据的节点,每个节点可以分配一个或多个数据表。
主机节点:Datahost:主机节点,每个主机可以分配一个或多个数据节点。
分表策略:根据分表策略决定数据写入到哪个节点。
管理信息:管理MYCAT连接和配置信息。

server.xml

用户连接mysql时使用的用户名,密码,逻辑库schemas对应下游数据库,在 schema.xml中有定义

  • 配置mycat连接信息
  • 一些性能优化等管理信息
	<user name="root">
		<property name="password">123456</property>
		<property name="schemas">toutiao-news</property>
	</user>

schema.xml

Schema.xml作为MyCat中重要的配置文件之一,管理着MyCat的逻辑库、表、分片规则、DataNode以及DataSource

  • 配置Mycat节点信息
  • 配置Mycat主机信息
  • 配置分表策略
  • 一些连接信息或者读写分离主机配置
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
	
	<schema name="toutiao-news" checkSQLschema="true" sqlMaxLimit="100">
		<!-- 全局表 -->
		<!-- 通用调度器quartz服务的调度表 -->
		<table name="QUARTZ_QRTZ_BLOB_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="QUARTZ_QRTZ_CALENDARS" dataNode="DNSQ" type="global"/>
		<table name="QUARTZ_QRTZ_CRON_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="QUARTZ_QRTZ_FIRED_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="QUARTZ_QRTZ_JOB_DETAILS" dataNode="DNSQ" type="global"/>
		<table name="QUARTZ_QRTZ_LOCKS" dataNode="DNSQ" type="global"/>
		<table name="QUARTZ_QRTZ_PAUSED_TRIGGER_GRPS" dataNode="DNSQ" type="global"/>
		<table name="QUARTZ_QRTZ_SCHEDULER_STATE" dataNode="DNSQ" type="global"/>
		<table name="QUARTZ_QRTZ_SIMPLE_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="QUARTZ_QRTZ_SIMPROP_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="QUARTZ_QRTZ_TRIGGERS" dataNode="DNSQ" type="global"/>
		<!-- 通用调度器quartz服务的调度表 -->
		<table name="CRAWLER_QRTZ_BLOB_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="CRAWLER_QRTZ_CALENDARS" dataNode="DNSQ" type="global"/>
		<table name="CRAWLER_QRTZ_CRON_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="CRAWLER_QRTZ_FIRED_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="CRAWLER_QRTZ_JOB_DETAILS" dataNode="DNSQ" type="global"/>
		<table name="CRAWLER_QRTZ_LOCKS" dataNode="DNSQ" type="global"/>
		<table name="CRAWLER_QRTZ_PAUSED_TRIGGER_GRPS" dataNode="DNSQ" type="global"/>
		<table name="CRAWLER_QRTZ_SCHEDULER_STATE" dataNode="DNSQ" type="global"/>
		<table name="CRAWLER_QRTZ_SIMPLE_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="CRAWLER_QRTZ_SIMPROP_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="CRAWLER_QRTZ_TRIGGERS" dataNode="DNSQ" type="global"/>
		<!-- 通用调度器MIGRATION_QRTZ服务的调度表 -->
		<table name="MIGRATION_QRTZ_BLOB_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="MIGRATION_QRTZ_CALENDARS" dataNode="DNSQ" type="global"/>
		<table name="MIGRATION_QRTZ_CRON_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="MIGRATION_QRTZ_FIRED_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="MIGRATION_QRTZ_JOB_DETAILS" dataNode="DNSQ" type="global"/>
		<table name="MIGRATION_QRTZ_LOCKS" dataNode="DNSQ" type="global"/>
		<table name="MIGRATION_QRTZ_PAUSED_TRIGGER_GRPS" dataNode="DNSQ" type="global"/>
		<table name="MIGRATION_QRTZ_SCHEDULER_STATE" dataNode="DNSQ" type="global"/>
		<table name="MIGRATION_QRTZ_SIMPLE_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="MIGRATION_QRTZ_SIMPROP_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="MIGRATION_QRTZ_TRIGGERS" dataNode="DNSQ" type="global"/>
		<!-- 通用调度器ADMIN_QRTZ服务的调度表 -->
		<table name="ADMIN_QRTZ_BLOB_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="ADMIN_QRTZ_CALENDARS" dataNode="DNSQ" type="global"/>
		<table name="ADMIN_QRTZ_CRON_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="ADMIN_QRTZ_FIRED_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="ADMIN_QRTZ_JOB_DETAILS" dataNode="DNSQ" type="global"/>
		<table name="ADMIN_QRTZ_LOCKS" dataNode="DNSQ" type="global"/>
		<table name="ADMIN_QRTZ_PAUSED_TRIGGER_GRPS" dataNode="DNSQ" type="global"/>
		<table name="ADMIN_QRTZ_SCHEDULER_STATE" dataNode="DNSQ" type="global"/>
		<table name="ADMIN_QRTZ_SIMPLE_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="ADMIN_QRTZ_SIMPROP_TRIGGERS" dataNode="DNSQ" type="global"/>
		<table name="ADMIN_QRTZ_TRIGGERS" dataNode="DNSQ" type="global"/>
		<!-- app_info -->
		<table name="ap_article" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40"/>
		
		<table name="ap_article_config" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40" />
		<table name="ap_article_content" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40" />

		<table name="ap_dynamic" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40" />
		<table name="ap_comment" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40" />
		<table name="ap_comment_repay" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40" />
		<table name="ap_user" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40"/>

		<table name="ap_user_identity" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40" />
		<table name="ap_user_realname" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40" />
		<table name="ap_user_info" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40" />

		<table name="ap_user_equipment" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40" />
		<table name="ap_user_follow" dataNode="DNAP_$0-39" rule="burst4040" />
		<table name="ap_user_fan" dataNode="DNAP_$0-39"  rule="burst4040" />
		<table name="ap_user_channel" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40" />
		<table name="ap_user_article_list" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40" />
		<table name="ap_user_dynamic_list" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40" />
		<table name="ap_user_letter" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40" />
		<table name="ap_user_message" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40" />
		<table name="ap_user_search" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40" />
		<table name="ap_user_feedback" dataNode="DNAP_$0-39" autoIncrement="true" primaryKey="id" rule="mod-long40" />
		<!--addtional-->
		<table name="ap_author" dataNode="DNAP_0" autoIncrement="true" primaryKey="id" />
		<!--add 2-->
		<table name="ap_associate_words" dataNode="DNAP_0"/>
		<table name="ap_hot_words" dataNode="DNAP_0"/>
		<table name="ap_hot_articles" dataNode="DNAP_0"/>


		<!-- app_behavior -->
		<table name="ap_show_behavior" dataNode="DNBE_$0-49" rule="mod-long50" autoIncrement="true" primaryKey="id"/>
		<table name="ap_unlikes_behavior" dataNode="DNBE_0" autoIncrement="true" primaryKey="id"/>
		<table name="ap_follow_behavior" dataNode="DNBE_1" autoIncrement="true" primaryKey="id"/>
		<table name="ap_share_behavior" dataNode="DNBE_2" autoIncrement="true" primaryKey="id"/>
		<table name="ap_login_behavior" dataNode="DNBE_$0-49" rule="mod-long" autoIncrement="true" primaryKey="id"/>
		<table name="ap_equipment" dataNode="DNBE_$0-49" rule="mod-long50" autoIncrement="true" primaryKey="id"/>
		<table name="ap_equipment_code" dataNode="DNBE_$0-49" rule="mod-long50" autoIncrement="true" primaryKey="id"/>
		<table name="ap_forward_behavior" dataNode="DNBE_7" autoIncrement="true" primaryKey="id"/>
		<table name="ap_behavior_entry" dataNode="DNBE_$0-49" rule="burst5050"/>
		<table name="ap_collection" dataNode="DNBE_$0-49" rule="burst5050"/>
		<table name="ap_likes_behavior" dataNode="DNBE_$0-49" rule="burst5050"/>
		<table name="ap_read_behavior" dataNode="DNBE_$0-49" rule="burst5050"/>
		<!-- wemedia -->
		<table name="wm_news_statistics" dataNode="DNWM_$0-5" rule="burst66"/>
		<table name="wm_sub_user" dataNode="DNWM_$0-2" rule="mod-long" autoIncrement="true" primaryKey="id"/>
		<table name="wm_user_auth" dataNode="DNWM_$1-3" rule="mod-long" autoIncrement="true" primaryKey="id"/>
		<table name="wm_user" dataNode="DNWM_$0-5" rule="mod-long6" autoIncrement="true" primaryKey="id"/>
		<table name="wm_user_login" dataNode="DNWM_4" autoIncrement="true" primaryKey="id"/>
		<table name="wm_user_equipment" dataNode="DNWM_$1-3" rule="mod-long" autoIncrement="true" primaryKey="id"/>
		<table name="wm_fans_statistics" dataNode="DNWM_$0-5" rule="burst66"/>
		<table name="wm_fans_portrait" dataNode="DNWM_$0-5" rule="mod-long6" autoIncrement="true" primaryKey="id"/>
		<!--addtional-->
		<table name="wm_material" dataNode="DNWM_0" autoIncrement="true" primaryKey="id" />
		<table name="wm_news" dataNode="DNWM_0" autoIncrement="true" primaryKey="id" />
		<table name="wm_news_material" dataNode="DNWM_0" autoIncrement="true" primaryKey="id" />
		<!-- crawlers -->
		<table name="cl_task_exception" dataNode="DNCL_$0-2" rule="mod-long" autoIncrement="true" primaryKey="id" />
		<table name="cl_task_log" dataNode="DNCL_$3-5" rule="mod-long" autoIncrement="true" primaryKey="id" />
		<table name="cl_news" dataNode="DNCL_$0-2" rule="mod-long" autoIncrement="true" primaryKey="id" />
		<table name="cl_news_comments" dataNode="DNCL_$0-2" rule="cl_news_id3" autoIncrement="true" primaryKey="id" />
		<table name="cl_news_material" dataNode="DNCL_$0-5" rule="cl_news_id6" autoIncrement="true" primaryKey="id" />
		<table name="cl_material" dataNode="DNCL_$0-5" rule="mod-long6" autoIncrement="true" primaryKey="id" />
		<table name="cl_news_additional" dataNode="DNCL_$3-5" rule="cl_news_id3" autoIncrement="true" primaryKey="id" />
		<table name="cl_ip_pool" dataNode="DNCL_0" autoIncrement="true" primaryKey="id" />
		<table name="cl_task" dataNode="DNCL_0" autoIncrement="true" primaryKey="id" />
		<!-- admin -->
		<table name="ad_article_statistics" dataNode="DNAD_$0-3" rule="mod-long4" autoIncrement="true" primaryKey="id" />
		<table name="ad_user_opertion" dataNode="DNAD_$0-3" rule="mod-long4" autoIncrement="true" primaryKey="id" />
		<table name="ad_user" dataNode="DNAD_0" autoIncrement="true" primaryKey="id" />
		<table name="ad_user_login" dataNode="DNAD_$0-3" rule="mod-long4" autoIncrement="true" primaryKey="id" />
		<table name="ad_user_role" dataNode="DNAD_0" autoIncrement="true" primaryKey="id" />
		<table name="ad_user_equipment" dataNode="DNAD_$0-3" rule="mod-long4" autoIncrement="true" primaryKey="id" />
		<table name="ad_menu" dataNode="DNAD_0" autoIncrement="true" primaryKey="id" />
		<table name="ad_role" dataNode="DNAD_0" autoIncrement="true" primaryKey="id" />
		<table name="ad_role_auth" dataNode="DNAD_0" autoIncrement="true" primaryKey="id" />
		<table name="ad_vistor_statistics" dataNode="DNAD_0" autoIncrement="true" primaryKey="id" />
		<table name="ad_function" dataNode="DNAD_0" autoIncrement="true" primaryKey="id" />
		<!--addtional-->
		<table name="ad_channel" dataNode="DNAD_0" autoIncrement="true" primaryKey="id" />
		<table name="ad_channel_label" dataNode="DNAD_0" autoIncrement="true" primaryKey="id" />
		<table name="ad_label" dataNode="DNAD_0" autoIncrement="true" primaryKey="id" />
		<table name="ad_recommend_strategy" dataNode="DNAD_0" autoIncrement="true" primaryKey="id" />
		<table name="ad_sensitive" dataNode="DNAD_0" autoIncrement="true" primaryKey="id" />
		<table name="ad_strategy_group" dataNode="DNAD_0" autoIncrement="true" primaryKey="id" />
	</schema>

	<dataNode name="DNSQ" dataHost="HOST0" database="app_seq" />
	<dataNode name="DNAP_0" dataHost="HOST0" database="app_info_0" />
	<dataNode name="DNAP_1" dataHost="HOST0" database="app_info_1" />
	<dataNode name="DNAP_2" dataHost="HOST0" database="app_info_2" />
	<dataNode name="DNAP_3" dataHost="HOST0" database="app_info_3" />
	<dataNode name="DNAP_4" dataHost="HOST0" database="app_info_4" />
	<dataNode name="DNAP_5" dataHost="HOST0" database="app_info_5" />
	<dataNode name="DNAP_6" dataHost="HOST0" database="app_info_6" />
	<dataNode name="DNAP_7" dataHost="HOST0" database="app_info_7" />
	<dataNode name="DNAP_8" dataHost="HOST0" database="app_info_8" />
	<dataNode name="DNAP_9" dataHost="HOST0" database="app_info_9" />
	<dataNode name="DNAP_10" dataHost="HOST0" database="app_info_10" />
	<dataNode name="DNAP_11" dataHost="HOST0" database="app_info_11" />
	<dataNode name="DNAP_12" dataHost="HOST0" database="app_info_12" />
	<dataNode name="DNAP_13" dataHost="HOST0" database="app_info_13" />
	<dataNode name="DNAP_14" dataHost="HOST0" database="app_info_14" />
	<dataNode name="DNAP_15" dataHost="HOST0" database="app_info_15" />
	<dataNode name="DNAP_16" dataHost="HOST0" database="app_info_16" />
	<dataNode name="DNAP_17" dataHost="HOST0" database="app_info_17" />
	<dataNode name="DNAP_18" dataHost="HOST0" database="app_info_18" />
	<dataNode name="DNAP_19" dataHost="HOST0" database="app_info_19" />
	<dataNode name="DNAP_20" dataHost="HOST0" database="app_info_20" />
	<dataNode name="DNAP_21" dataHost="HOST0" database="app_info_21" />
	<dataNode name="DNAP_22" dataHost="HOST0" database="app_info_22" />
	<dataNode name="DNAP_23" dataHost="HOST0" database="app_info_23" />
	<dataNode name="DNAP_24" dataHost="HOST0" database="app_info_24" />
	<dataNode name="DNAP_25" dataHost="HOST0" database="app_info_25" />
	<dataNode name="DNAP_26" dataHost="HOST0" database="app_info_26" />
	<dataNode name="DNAP_27" dataHost="HOST0" database="app_info_27" />
	<dataNode name="DNAP_28" dataHost="HOST0" database="app_info_28" />
	<dataNode name="DNAP_29" dataHost="HOST0" database="app_info_29" />
	<dataNode name="DNAP_30" dataHost="HOST0" database="app_info_30" />
	<dataNode name="DNAP_31" dataHost="HOST0" database="app_info_31" />
	<dataNode name="DNAP_32" dataHost="HOST0" database="app_info_32" />
	<dataNode name="DNAP_33" dataHost="HOST0" database="app_info_33" />
	<dataNode name="DNAP_34" dataHost="HOST0" database="app_info_34" />
	<dataNode name="DNAP_35" dataHost="HOST0" database="app_info_35" />
	<dataNode name="DNAP_36" dataHost="HOST0" database="app_info_36" />
	<dataNode name="DNAP_37" dataHost="HOST0" database="app_info_37" />
	<dataNode name="DNAP_38" dataHost="HOST0" database="app_info_38" />
	<dataNode name="DNAP_39" dataHost="HOST0" database="app_info_39" />
	<dataNode name="DNBE_0" dataHost="HOST0" database="app_behavior_0" />
	<dataNode name="DNBE_1" dataHost="HOST0" database="app_behavior_1" />
	<dataNode name="DNBE_2" dataHost="HOST0" database="app_behavior_2" />
	<dataNode name="DNBE_3" dataHost="HOST0" database="app_behavior_3" />
	<dataNode name="DNBE_4" dataHost="HOST0" database="app_behavior_4" />
	<dataNode name="DNBE_5" dataHost="HOST0" database="app_behavior_5" />
	<dataNode name="DNBE_6" dataHost="HOST0" database="app_behavior_6" />
	<dataNode name="DNBE_7" dataHost="HOST0" database="app_behavior_7" />
	<dataNode name="DNBE_8" dataHost="HOST0" database="app_behavior_8" />
	<dataNode name="DNBE_9" dataHost="HOST0" database="app_behavior_9" />
	<dataNode name="DNBE_10" dataHost="HOST0" database="app_behavior_10" />
	<dataNode name="DNBE_11" dataHost="HOST0" database="app_behavior_11" />
	<dataNode name="DNBE_12" dataHost="HOST0" database="app_behavior_12" />
	<dataNode name="DNBE_13" dataHost="HOST0" database="app_behavior_13" />
	<dataNode name="DNBE_14" dataHost="HOST0" database="app_behavior_14" />
	<dataNode name="DNBE_15" dataHost="HOST0" database="app_behavior_15" />
	<dataNode name="DNBE_16" dataHost="HOST0" database="app_behavior_16" />
	<dataNode name="DNBE_17" dataHost="HOST0" database="app_behavior_17" />
	<dataNode name="DNBE_18" dataHost="HOST0" database="app_behavior_18" />
	<dataNode name="DNBE_19" dataHost="HOST0" database="app_behavior_19" />
	<dataNode name="DNBE_20" dataHost="HOST0" database="app_behavior_20" />
	<dataNode name="DNBE_21" dataHost="HOST0" database="app_behavior_21" />
	<dataNode name="DNBE_22" dataHost="HOST0" database="app_behavior_22" />
	<dataNode name="DNBE_23" dataHost="HOST0" database="app_behavior_23" />
	<dataNode name="DNBE_24" dataHost="HOST0" database="app_behavior_24" />
	<dataNode name="DNBE_25" dataHost="HOST0" database="app_behavior_25" />
	<dataNode name="DNBE_26" dataHost="HOST0" database="app_behavior_26" />
	<dataNode name="DNBE_27" dataHost="HOST0" database="app_behavior_27" />
	<dataNode name="DNBE_28" dataHost="HOST0" database="app_behavior_28" />
	<dataNode name="DNBE_29" dataHost="HOST0" database="app_behavior_29" />
	<dataNode name="DNBE_30" dataHost="HOST0" database="app_behavior_30" />
	<dataNode name="DNBE_31" dataHost="HOST0" database="app_behavior_31" />
	<dataNode name="DNBE_32" dataHost="HOST0" database="app_behavior_32" />
	<dataNode name="DNBE_33" dataHost="HOST0" database="app_behavior_33" />
	<dataNode name="DNBE_34" dataHost="HOST0" database="app_behavior_34" />
	<dataNode name="DNBE_35" dataHost="HOST0" database="app_behavior_35" />
	<dataNode name="DNBE_36" dataHost="HOST0" database="app_behavior_36" />
	<dataNode name="DNBE_37" dataHost="HOST0" database="app_behavior_37" />
	<dataNode name="DNBE_38" dataHost="HOST0" database="app_behavior_38" />
	<dataNode name="DNBE_39" dataHost="HOST0" database="app_behavior_39" />
	<dataNode name="DNBE_40" dataHost="HOST0" database="app_behavior_40" />
	<dataNode name="DNBE_41" dataHost="HOST0" database="app_behavior_41" />
	<dataNode name="DNBE_42" dataHost="HOST0" database="app_behavior_42" />
	<dataNode name="DNBE_43" dataHost="HOST0" database="app_behavior_43" />
	<dataNode name="DNBE_44" dataHost="HOST0" database="app_behavior_44" />
	<dataNode name="DNBE_45" dataHost="HOST0" database="app_behavior_45" />
	<dataNode name="DNBE_46" dataHost="HOST0" database="app_behavior_46" />
	<dataNode name="DNBE_47" dataHost="HOST0" database="app_behavior_47" />
	<dataNode name="DNBE_48" dataHost="HOST0" database="app_behavior_48" />
	<dataNode name="DNBE_49" dataHost="HOST0" database="app_behavior_49" />
	<dataNode name="DNWM_0" dataHost="HOST0" database="wemedia_0" />
	<dataNode name="DNWM_1" dataHost="HOST0" database="wemedia_1" />
	<dataNode name="DNWM_2" dataHost="HOST0" database="wemedia_2" />
	<dataNode name="DNWM_3" dataHost="HOST0" database="wemedia_3" />
	<dataNode name="DNWM_4" dataHost="HOST0" database="wemedia_4" />
	<dataNode name="DNWM_5" dataHost="HOST0" database="wemedia_5" />
	<dataNode name="DNCL_0" dataHost="HOST0" database="crawlers_0" />
	<dataNode name="DNCL_1" dataHost="HOST0" database="crawlers_1" />
	<dataNode name="DNCL_2" dataHost="HOST0" database="crawlers_2" />
	<dataNode name="DNCL_3" dataHost="HOST0" database="crawlers_3" />
	<dataNode name="DNCL_4" dataHost="HOST0" database="crawlers_4" />
	<dataNode name="DNCL_5" dataHost="HOST0" database="crawlers_5" />
	<dataNode name="DNAD_0" dataHost="HOST0" database="admin_0" />
	<dataNode name="DNAD_1" dataHost="HOST0" database="admin_1" />
	<dataNode name="DNAD_2" dataHost="HOST0" database="admin_2" />
	<dataNode name="DNAD_3" dataHost="HOST0" database="admin_3" />

	<dataHost name="HOST0" maxCon="600" minCon="200" balance="0"
	                  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
	        <heartbeat>select user()</heartbeat>
	        <writeHost host="HOST0_M" url="47.94.7.85:3306" user="root" password="root"/>
	</dataHost>

</mycat:schema>

dataNode : 数据节点 dataNode=“DNBE_$0-49” 数据存储在0 - 49 号节点上
table_name:表名,物理表
type=“global”: 不进行分库分表,只存在该数据节点上
rule=“mod-long50” 对50取余,余数存放在对应节点上
autoIncrement=“true” id 自增
primaryKey=“id” 自增主键

<dataHost name="HOST0" maxCon="600" minCon="200" balance="0"
	                  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
	        <heartbeat>select user()</heartbeat>
	        <writeHost host="HOST0_M" url="note01:3306" user="root" password="000000"/>
	</dataHost>

对应真实数据库的账户以及密码

  • ame:主机节点名称
  • minCon:最小连接线程
  • maxCon:最大连接线程
  • balance:负载均衡策略
  • writeHost 该标签配置节点对应的mysql主机

rule.xml

  • 配置 function class指定分片算法 本例为求余算法
  • 配置 tableRule 设置对那个字段执行分片操作 本例为id对40求余
<function name="mod-long40" class="io.mycat.route.function.PartitionByMod">
		<!-- how many data nodes -->
		<property name="count">40</property>
	</function>
	
	<tableRule name="mod-long40">
		<rule>
			<columns>id</columns>
			<algorithm>mod-long40</algorithm>
		</rule>
	</tableRule>

sequence_db_conf.properties

该文件为全局自增主键配置对于table定义了autoIncrement=“true” primaryKey="id"的表,需要配置全局自增序号(注意全大写)
第一列表名=DNSQ

#sequence stored in datanode
MYCAT=DNSQ
AP_ARTICLE=DNSQ
AP_ARTICLE_CONFIG=DNSQ
AP_ARTICLE_CONTENT=DNSQ
AP_DYNAMIC=DNSQ
AP_COMMENT=DNSQ
AP_COMMENT_REPAY=DNSQ
AP_USER=DNSQ
AP_USER_IDENTITY=DNSQ
AP_USER_REALNAME=DNSQ
AP_USER_INFO=DNSQ
AP_USER_EQUIPMENT=DNSQ
AP_USER_CHANNEL=DNSQ
AP_USER_ARTICLE_LIST=DNSQ
AP_USER_DYNAMIC_LIST=DNSQ

同时在DNSQ也就是app_seq表里插入一条记录:

INSERT INTO `app_seq`.`MYCAT_SEQUENCE` (`name`, `current_value`, `increment`) VALUES ('ap_article', '1000', '1000');
  • current_value:为初始值
  • increment:为每次获取序列的自增值,该值的数据根据对应表的数据新增速率设置。

连接mycat

数据库中间件Mycat_第2张图片
对应的库名为之前schema.xml 中的逻辑库

自定义mycat 路由实现动态扩容

将jar包加入项目
maven加载jar包配置

   <dependencies>
        <dependency>
            <groupId>com.mycat</groupId>
            <artifactId>mycat-server</artifactId>
            <version>1.0.0</version>
            <scope>system</scope>
            <systemPath>${basedir}/libs/Mycat-server-1.6-RELEASE.jar</systemPath>
        </dependency>
    </dependencies>

分片中含有字段规范命名为burst,类型为String,值格式为dataId-分表ID,dataId用于分组ID计算,为数据量提供扩展性;分表ID用于组内表的分配,其分片公式如下:

分片ID = (dataId/volume)* step +分表ID/mod 
  • dataId 主键id

  • Volume是每组分片的数据容量

  • Step是每组分片的DateNode数量

  • Mode是表在每组分片中的节点数量

算法实现

1.- 创建类文件:BurstRuleAlgorithm

  • 修改类继承AbstractPartitionAlgorithm 和实现RuleAlgorithm接口

  • 在类中定义volume、step、mod三个变量,并提供set方法

  • 实现calculate 等值分片DN计算方法(参数是burst值)

  • 实现calculateRange范围分片DN计算方法(参数是burst值)

package com.zyd;

import io.mycat.config.model.rule.RuleAlgorithm;
import io.mycat.route.function.AbstractPartitionAlgorithm;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class BurstRuleAlgorithm extends AbstractPartitionAlgorithm implements RuleAlgorithm {
    // 单组数据容量
    Long volume;
    // 单组DN节点数量
    Integer step;
    // 分片模
    Integer mod;

    @Override
    public Integer calculate(String columnValue) {
        if(columnValue!=null){
            String[] temp = columnValue.split("-");
            if(temp.length==2){
                try {
                    Long dataId = Long.valueOf(temp[0]);
                    Long burstId = Long.valueOf(temp[1]);
                    int group = (int)(dataId/volume)*step;
                    int pos = group + (int)(burstId%mod);
                    System.out.println("HEIMA RULE INFO ["+columnValue+"]-[{"+pos+"}]");
                    return pos;
                }catch (Exception e){
                    System.out.println("HEIMA RULE INFO ["+columnValue+"]-[{"+e.getMessage()+"}]");
                }
            }
        }
        return 0;
    }

    @Override
    public Integer[] calculateRange(String beginValue, String endValue) {
        if(beginValue!=null&&endValue!=null){
            Integer begin = calculate(beginValue);
            Integer end = calculate(endValue);
            if(begin == null || end == null){
                return new Integer[0];
            }
            if (end >= begin) {
                int len = end - begin + 1;
                Integer[] re = new Integer[len];
                for (int i = 0; i < len; i++) {
                    re[i] = begin + i;
                }
                return re;
            }
        }
        return new Integer[0];

    }
}

将项目打包并放置于mycat的lib目录下,对于,rule.xml配置

	<function name="burst5050" class="com.zyd.BurstRuleAlgorithm">
		<property name="volume">500000000</property><!-- 单组容量 -->
		<property name="step">50</property><!-- 单组节点量 -->
		<property name="mod">50</property><!-- 单组数据mod -->
	</function>
<!-- 引用 -->
	<tableRule name="burst5050">
		<rule>
			<columns>burst</columns>
			<algorithm>burst5050</algorithm>
		</rule>
	</tableRule>

对应schema.xml中

<table name="ap_user_follow" dataNode="DNAP_$0-39" rule="burst4040" />

使用数据库查询工具列出执行计划

explain select id from ap_behavior_entry where burst in ('1-1'.'3-2')

在程序中要正确的插入数据,需要给对应表增加burst字段,并在程序中拼接字段值,同时数据主键id的值需要在程序中生成(既项目中使用ZKSEQUENCE方式生成),例:

程序中拼接字段值:

alb.setId(sequences.sequenceApLikes());//设置主键
alb.setBurst(BurstUtils.encrypt(alb.getId(),alb.getBehaviorEntryId()));//设置分片

Mapper.xml中正常插入:

<insert id="insert" parameterType="com.heima.article.mysql.core.model.pojos.app.ApLikesBehavior" >
  insert into ap_likes_behavior (id, behavior_entry_id, entry_id, type, operation, created_time,burst)
  values (#{id}, #{behaviorEntryId}, #{entryId}, #{type}, #{operation},
    #{createdTime},#{burst})
</insert>

程序-数据查询

  • 【问题】

数据查询的问题有两点:

1、不能明确数据id,所以无法直接拼接burst

2、 burst字段用于分片,写在where条件之后不够优雅

  • 【解决方案】

第一个问题查询时可假定id为0,既默认为在第一组中查询,以后有多组时可以默认每组第一个数据id;这样设计的原因是只要组容量内的id和第一个数据id计算出的结果一致。

第二个问题可以通过Mycat提供的注解语法优雅的编写我们的SQL。

  • 【示例】

综合以上解决思路,代码实现的示例如下:

<select id="selectLastLike" resultMap="BaseResultMap">
  /*!mycat:sql=select id from ap_likes_behavior where burst='${burst}'*/
    select * from ap_likes_behavior where behavior_entry_id=#{objectId} and entry_id=#{entryId} and type=#{type} order by created_time desc limit 1
</select>

以上代码在Mycat中执行,首先会执行注解代码确定SQL路由的指定节点,然后再分发SQL具体执行。其中注解中的burst有多个可以使用in,其值需用$连接(由于burst字段完全有后端程序控制值,所以这里不存在外部安全问题),否则会抛出预编译参数不匹配的问题。

程序-数据更新

数据更新请参考《数据查询》

程序-数据删除

数据删除请参考《数据查询》

ap_show_behavior数据是通过批量方式插入的,集成Mycat之后,需要使用注解,以便实现注解的托管生成。

<insert id="saveBehaviors">
  /*!mycat:catlet=io.mycat.route.sequence.BatchInsertSequence */
  insert into ap_show_behavior ( entry_id, article_id,is_click, show_time, created_time) values  
    <foreach item="item" collection="articleIds" separator=",">    
        (#{entryId}, #{item},0, now(),now())  
    foreach>
insert>

你可能感兴趣的:(Mysql)