技术分享 | 数据库产品选型测试 集中式与分布式

前文

数据库派别分为集中式和分布式,谁强谁弱,一直争论不休。什么样的场景用上集中式数据库,什么时候适合用分布式,分库分表的契机在哪里? 纸上得终学浅,绝知此事要躬行。还是需要做下测试,测试之前在各个博客与官网上做了大量的调研,宏观上基于shardingproxy上面进行sysbench测试,后面证实我也走过各位博主的坑。整体而言,不敢说100%的科学严谨,比起一些博主的结论严谨很多。

测试环境

ip mysql版本 角色 硬件配置
192.168.10.160 mysql 5.7、shardingproxy 5.1.0 shardingproxy 角色、mysql节点、 sysbench客户端执行 8C,12G
192.168.153.128 mysql 5.7 mysql节点 8C,6g

测试思路

  • 数据量级从500万起、1000万级别、5000万级往上递进【后面直接用5000万】
  • SQL语句采用sysbench的oltp_read_write.lua
  • 调整虚拟机CPU核数,逐步从1升到8,观察 sysbench的QPS和TPS以及CPU、内存、IO的消耗
  • 针对MYSQL单机测试不用 数据量级别下的QPS和TPS、以及CPU、内存、IO的消耗
  • 针对shardingproxy转发单个MYSQL,并观测QPS和TPS、以及CPU、内存、IO的消耗
  • 针对shardingproxy转发两个MYSQL,并观测QPS和TPS、以及CPU、内存、IO的消耗
  • 基于shardingproxy,基于原生语句DistSQL创建单表,创建分片规则,并通过 insert插 入大量数据,观测QPS和TPS、以及CPU、内存、IO的消耗
  • 通过sysbench生成相关数据,测试数据、销毁数据

环境了解

  • oltp_read_write.lua覆盖7个动作 execute_simple_ranges(),execute_sum_ranges()、 execute_order_ranges()、execute_distinct_ranges()、execute_index_updates()、execute_non_index_updates()、execute_delete_inserts(),某个程度,oltp_read_write.lua代表sysbench最有代表性的TPS和QPS的测试选项。
makefile 复制代码
sum_ranges = {
      "SELECT SUM(k) FROMsbtest%u WHERE id BETWEEN ? AND ?",
       t.INT, t.INT},
order_ranges = {
      "SELECT c FROMsbtest%u WHERE id BETWEEN ? AND ? ORDER BY c",
       t.INT, t.INT},
distinct_ranges = {
      "SELECT DISTINCT cFROM sbtest%u WHERE id BETWEEN ? AND ? ORDER BY c",
      t.INT, t.INT},
index_updates = {
      "UPDATE sbtest%uSET k=k+1 WHERE id=?",
      t.INT},
non_index_updates = {
      "UPDATE sbtest%uSET c=? WHERE id=?",
      {t.CHAR, 120}, t.INT},
deletes = {
      "DELETE FROMsbtest%u WHERE id=?",
      t.INT},
inserts = {
      "INSERT INTOsbtest%u (id, k, c, pad) VALUES (?, ?, ?, ?)",
      t.INT, t.INT, {t.CHAR,120}, {t.CHAR, 60}}
  • mysql5.7保留原有的内存管理参数不变,也会稍做调整,目前测试性能强弱结论与内存管理没有关系
  • shardingproxy使用默认的配置参数,默认支持XA事务,没有任何变化。

执行操作

ruby 复制代码
​
试了几个版本的shardingproxy,目前只有5.10的能够成功启动没有报错
​
​
shardingproxy5.10的server.yaml,主要有以下参数
​
rules:
  - !AUTHORITY
    users:
      - root@%:root
      - sharding@:sharding
    provider:
      type: ALL_PRIVILEGES_PERMITTED
  - !TRANSACTION
    defaultType: XA
    providerType: Atomikos
​
​
​
启动shardingproxy5.10
​
​
[root@server128 apache-shardingsphere-5.1.0-shardingsphere-proxy-bin]# ./bin/start.sh
/usr/bin/java
we find java version: java8, full_version=1.8.0_382, full_path=/usr/bin/java
The classpath is /root/sharding/apache-shardingsphere-5.4.1-shardingsphere-proxy-bin/conf:/root/sharding/apache-shardingsphere-5.4.1-shardingsphere-proxy-bin/conf:.:/root/sharding/apache-shardingsphere-5.4.1-shardingsphere-proxy-bin/lib/*:/root/sharding/apache-shardingsphere-5.4.1-shardingsphere-proxy-bin/ext-lib/*
main class org.apache.shardingsphere.proxy.Bootstrap -1 /root/sharding/apache-shardingsphere-5.4.1-shardingsphere-proxy-bin/conf 0.0.0.0 false
Starting the ShardingSphere-Proxy ... PID: 50193
​
登陆shard-shell
​
​
​
mysql  -h192.168.153.128 -P 3307  -uroot -proot
​
​
shardingproxy创建数据库,代表对外可见的,映射的逻辑数据库
​
mysql> create database tpcc;
Query OK, 0 rows affected (0.02 sec)
​
使用tpcc
mysql> use tpcc;
Query OK, 0 rows affected (0.02 sec)
​
​
​
添加数据源tpcc2_1、tpcc2_2
​
add resource tpcc2_1(url="jdbc:mysql://127.0.0.1:3306/tpcc2?serverTimezone=UTC&useSSL=false",user=henley,password=Gmcc@1234,
PROPERTIES("maximumPoolSize"=300,"idleTimeout"="30000")
);
​
add resource tpcc2_2(URL="jdbc:mysql://192.168.10.160:3306/tpcc2?useSSL=false&useUnicode=true&characterEncoding=UTF-8",
USER=henley,
PASSWORD=Gmcc@1234,
PROPERTIES("maximumPoolSize"=300,"idleTimeout"="30000")
);
​
​
DistSQL亮睛的地方,创建分片表,挂接tpcc2_1,tpcc2_2数据源,选用id作为分片键,hash_mod的算法,一共分成6份,ShardingSphere支持两种分布式主键生成策略:UUID和雪花算法SNOWFLAKE,此处选用雪花算法SNOWFLAKE。
​
​
CREATE SHARDING TABLE RULE sbtest1(
RESOURCES(tpcc2_1,tpcc2_2),
SHARDING_COLUMN=id,
TYPE(NAME=hash_mod,PROPERTIES("sharding-count"=6)),
KEY_GENERATE_STRATEGY(COLUMN=k,TYPE(NAME=snowflake))
);
​
​
shardingproxy创建表sbtest1,此外将会映射后端tpcc2_1,tpcc2_2数据源,将会生成6个表,
CREATE TABLE `sbtest1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `k` int(11) NOT NULL DEFAULT '0',
  `c` char(120) NOT NULL DEFAULT '',
  `pad` char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `k_1` (`k`)
) ENGINE=InnoDB;
​
​
简而言之,shardingproxy对外开发的表sbtest1,映射在后端的两个mysql的6个表上面,6 个表同样的结构。客户端对sbtest1的写,根据id将会错落到不同的数据源表上面。
​
​
​
mysql导出数据,不含表结构
​
mysqldump -h127.0.0.1 -P3306  -u henley -pGmcc@1234  --no-create-info --skip-extended-insert --complete-insert  tpcc3 sbtest1 >tpcc3_sbtest1.sql
​
​
针对本机的mysql的3个表,每个表是500万,发动6线程压测
​
sysbench /usr/share/sysbench/oltp_read_write.lua --mysql-host=127.0.0.1 --mysql-port=3306  --mysql-db=tpcc  --mysql-user=henley --mysql-password=Gmcc@1234   --table_size=5000000 --tables=3 --time=1200 --events=0 --threads=6   --report-interval=10 run
​
​
针对shardingproxy的sysbench压测
​
sysbench /usr/share/sysbench/oltp_read_write.lua --mysql-host=192.168.153.128 --mysql-port=3307  --mysql-db=tpcc  --mysql-user=root --mysql-password=root   --table_size=5000000 --tables=3 --time=1200 --events=0 --threads=6   --report-interval=10 run
​
​
​
​
​
​

测试记录

直接MYSQL压测

不同CPU核数、不同线程的500万的数据集,首先从默认的8核CPU,从1线程 开始一直到6线程,最后把CPU核数降为2核

直接shardingproxy压测

less 复制代码
add resource ds_0(url="jdbc:mysql://192.168.153.128:3306/tpcc?serverTimezone=UTC&useSSL=false",user=henley,password=Gmcc@1234);
​
​
​
mysql> show single tables;
+------------+---------------+
| table_name | resource_name |
+------------+---------------+
| sbtest2    | ds_0          |
| sbtest1    | ds_0          |
| sbtest3    | ds_0          |
+------------+---------------+
3 rows in set (0.07 sec)
​
​
​
​

同样基于500万数据集,shardingproxy后面挂着一个数据源【MYSQL】,基于先前针对MYSQL的参数配置,发现TPQ和QPS都降低了,和其它网友的踩坑一样ShardingSphere实践(5)------性能测试

怀疑是数据量的问题和数据入口的方式不对【shardingproxy 有数据分片规则】,于是从单机mysql导出5000万数据,从shardingproxy 以insert 的方式插入,后端数据源是两个mysql,插入时间花了3天。这样遵从shardingproxy 的规则进行了5000万的插入。

bash 复制代码
​
导出单机5000万的数据
mysqldump -h127.0.0.1 -P3306  -u henley -pGmcc@1234  --no-create-info --skip-extended-insert --complete-insert  tpcc3 sbtest1 >tpcc3_sbtest1.sql
​
基于shard_proxy的shell上执行  source   /path/tpcc3_sbtest1.sql;
自动把5000万的数据分片从入口的方式分摊到两个mysql上面。
​

再次通过sysbench进行压测试,发生性能依旧不理想,比直接mysql要慢。同时发现一个重要参数修改,Sharding-Proxy接入的分布式事务API支持LOCAL,XA,BASE类型的事务。我原来用的是XA,我把它更换成LOCAL,XA是标准的可靠的安全事务,但是性能低, 而LOCAL可能会有事务出错的风险。

但是我把XA换成LOCAL,依然性能低下。我再次比较了直连mysql和 shardingproxy的IO读写数据对比,两者差异很大,Sharding-Proxy的IO根本进入繁忙状态 。业务逻辑语句不变,数据底座的IO读写强弱就令人深思了。

过程记录

一个性能测试与SQL、数据量、结构表以及硬件状况相关, mysql5.7单机500万数据集如下。

cpu 线程 tps qps
8核 1 94 1892
8核 2 274 5497
8核 6 546 10935
2核 6 130 2800
  • mysql5.7单机500万、1000万、5000万的数据集的oltp_read_write.lua测试,shardingproxy外挂都要比mysql5.7要弱,而且占用的CPU、内存、IO要比mysql5.7要搞
  • 增加innodb_buffer可以明显提高mysql5.7单机的sysbench测试处理,但是对shardingproxy的提升表现不明显。
  • sysbench内含语句是针对单表的随机增删查改,考验的是一个DBMS的处理能力。MYSQL默认InnoDB引擎,按照 sbtest1的表结构,估摸即使1亿多的数据也能在3次硬盘寻道的范围内返回。
  • CPU个数和线程可以提高sysbench的处理能力,从虚拟机CPU个数据调整 ,从1到8,性能上升。sysbench的线程标准设置是6线程,6~8可以达到sysbench的性能高锋,即使把sysbench调整到50,由于没有相关的CPU核心支撑,所以不能发挥相应的作用。 CPU个数和sysbench线程 个数成正比。
  • 通过聚合函数例count统计5000万的数据量,根据测试,假使数据量越来越大,直连shardingproxy的SQL执行性能要比直接MYSQL要快。
  • 大量插入数据的时候,数据在剧烈增长变化过程中,这时聚合查询count(*)shardingproxy的查询响应速度相对 查询mysql要快。

结论

  • 从500万上升到1000万、5000万,观察硬盘利用率没有使用100%,单机5.7的IO仍有空闲,随着CPU核数提高会进入过多的繁忙,提高innodb_buffer可以提高sysbench性能, 如果需要更大程度的提高,必须要提高CPU个数
  • sysbench测试,数据量级上升从500万、1000万级别、5000级,mysql5.7单机处理性能TPS、QPS比同样的shardingproxy后带一个mysql5.7或者shardingproxy后带两个mysql5.7要强
  • 直接点查询、范围查询、单表组合查询不推荐使用shardingproxy进行分库分表,聚合查询或者大笔数据可以借助shardingproxy进行加强。
  • 解读两个对比IO读写集中问题,直连mysql代表的是集中式的架构,直连sharding-proxy是分布式的架构代码,在数据库管理系统支持的能力范围内,增删查改的选择【selection]和投影【projection】是数据库的强项。转入XA事务,除了逻辑链路增加,sharding-proxy还需要保障每个事务协同,这样的损耗就增多了。聚合函数几乎都是要对所有的数据进行全盘扫描的,索引的优越性没有体现出来,随着数据量的增大,B+树的体量大了,对于dbms造成必定的压力,这时候多个DBMS反而减轻了压力。这时候 sharding-proxy的好处用上来了。

最后想到的shardingproxy如此,其它分布式数据库必然因为2pc带来的单机性能影响下降,5000万的数据量覆盖了多少业务场景 ,除了常规的点查询语句,我需要进行什么样的分析需求才会选择一个分布式产品。选择的前提,除非MySQL各方面的调优都无法满足业务的需求

相关推荐
終不似少年遊*18 分钟前
图论1基础内容
数据结构·python·学习·算法·图论
游是水里的游29 分钟前
【算法day1】数组:双指针算法
数据结构·算法
不修×蝙蝠33 分钟前
数据结构--链表实现栈和队列
java·数据结构·链表··队列
web1309332039839 分钟前
RabbitMQ 篇-深入了解延迟消息、MQ 可靠性(生产者可靠性、MQ 可靠性、消费者可靠性)
数据库·分布式·rabbitmq
2401_8582861139 分钟前
102.【C语言】数据结构之用堆对数组排序
c语言·开发语言·数据结构·算法·
一二小选手1 小时前
【Mybatis】动态SQL详解
数据库·sql·mybatis
微扬嘴角1 小时前
Redis(概念、IO模型、多路选择算法、安装和启停)
数据库·redis·缓存
.ccc.。1 小时前
mysql定位慢查询以及分析原因
数据库·mysql
ydm_ymz1 小时前
实验07---7-11 一维数组的次大值
c语言·数据结构·算法
半桶水专家1 小时前
MySQL遇到“ Access denied for user ”问题的解决办法
数据库·mysql·adb