1 场景
当我们要记录用户在使用系统期间相关操作时,会产生大量数据,可以根据日期,将其平均分布到所有数据库分片中,以分散单节点压力。
2 实现原理
按日期分片,需要设定日期的格式和日期范围。
3 修改配置文件
3.1 修改 schema.xml 文件
在 schema 节点下新添加一个用于按日期分片的 table 节点,这里使用的数据表为 user_logs。
- name 用于分片的数据表 user_logs;
- dataNode 用于存储数据的节点;
- rule 对数据进行分片的规则名 partition_by_date。
<table name="user_logs" dataNode="dn1,dn2" rule="partition_by_date">\</table>
修改后的配置文件片段如下
3.2 修改 rule.xml 文件
3.2.1 添加 tableRule 节点
在 rule.xml 文件中添加按日期分片的规则。
- name 对数据进行分片的规则名 partition_by_date,与 schema.xml中配置对应;
- columns 用来作分片的列
- algorithm 实现分片的方法名
<tableRule name="partition_by_date">
<rule>
<columns>operate_time</columns>
<algorithm>partitionbyday</algorithm>
</rule>
</tableRule>
3.2.2 添加 function 节点
在 rule.xml 文件中添加 function ,用于具体分片的实际算法。
- name 实现分片的方法名,与 tableRule 下 algorithm 标签内容对应;
- class 实现算法的具体java类;
- dateFormat 用于分片字段的日期格式
- sNaturalDay 是否按自然日分片,0不走自然日,1为按自然日
- sBeginDate 日期范围的开始日期
- sEndDate 日期范围的结束日期
- sPartionDay 每一分片保存的连续天数,在同一个分片保存满5天后,切换到另一分片
需要注意的是
(sEndDate - sBeginDate)/sPartionDay 计算结果,向上取整后,应该等于所要分片的节点数:
- 如果大于分片的节点数,mycat启动时会报错;
- 如果小于分片的节点数,mycat将不会进行分片;
- 所有插入的数据,日期应大于等于 sBeginDate;
- 当记录中的日期超过sEndDate时,记录会根据 (当前日期 - sBeginDate)/sPartionDay 的计算结果,决定记录要保存于哪个分片中。
<function name="partitionbyday" class="io.mycat.route.function.PartitionByDate">
<property name="dateFormat">yyyy-MM-dd</property>
<property name="sNaturalDay">0</property>
<property name="sBeginDate">2001-01-01</property>
<property name="sEndDate">2001-01-10</property>
<property name="sPartionDay">5</property>
</function>
4 重启mycat
mycat restart
5 验证
进入到mycat数据端口。
5.1 创建表
create table user_logs(id int auto_increment primary key, user_id int, operate_time date, operate_type varchar(50));
5.2 插入数据
向表中插入多条数据
insert into USER_LOGS(id, user_id, operate_time,operate_type) values(1, 1001, '2001-01-01', 'login');
insert into USER_LOGS(id, user_id, operate_time,operate_type) values(2, 1001, '2001-01-02', 'logout');
insert into USER_LOGS(id, user_id, operate_time,operate_type) values(3, 1001, '2001-01-03', 'delete user1');
insert into USER_LOGS(id, user_id, operate_time,operate_type) values(4, 1001, '2001-01-07', 'delete user2');
insert into USER_LOGS(id, user_id, operate_time,operate_type) values(5, 1001, '2001-01-10', 'add user3');
insert into USER_LOGS(id, user_id, operate_time,operate_type) values(6, 1001, '2001-01-11', 'add user4');
insert into USER_LOGS(id, user_id, operate_time,operate_type) values(7, 1001, '2022-01-11', 'add user5');
insert into USER_LOGS(id, user_id, operate_time,operate_type) values(8, 1001, '2022-01-16', 'add user6');