mysql-cluster7.6.8应用测试,对比单机innodb

接上篇 mysql-cluster7.6.8 安装笔记,auto-installer体验


应用测试

java连接jdbc连接url调整:

jdbc:mysql:loadbalance://192.168.1.174:3306,192.168.1.176:3306/test_db?roundRobinLoadBalance=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8

建一张表,包含各种数据类型字段

mysql-cluster7.6.8应用测试,对比单机innodb_第1张图片

先造一批数据写入,确保测试数据的合理性,此处用到随机生成汉字、随机字母、随机数字

// 随机汉字
public static String getRandomStr(long length) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append((char) (0x4e00 + (int) (Math.random() * (0x9fa5 - 0x4e00 + 1))));
        }
        return sb.toString();
}

测试数据效果是这样婶儿的

mysql-cluster7.6.8应用测试,对比单机innodb_第2张图片

空表开始

       -> 单条连续插入100条,行数据0.3k左右
       => ndbcluster:平均0.03s/条
       => 单机innodb 平均0.03s/条

       -> ndbcluster:停用其中一个sql节点,单条连续插入100条
       => 可以成功写入,可以看到多数请求在0.03s,穿插少数请求在1.03s,可以看出集群容错在起作用
       => 继续停用一个data节点,仍可正常写入数据,效果同上
       => 继续停用一个manage节点,仍可正常写入数据,效果同上
新增节点
      由于NoOfReplicas设置2,且只有两个数据节点,等同于每个节点都具备完整数据,所以这样的测试意义不大,于是又增加了2两个数据节点,分别在两个服务器上,后续的测试针对4个数据节点+2个sql节点+2个manage节点进行。新增节点默认不会分布数据,需要手动操作:

# 进入管理节点shell客户端
ndb_mgm

# 当前各节点状态(可以看到新增节点显示no nodegroup,这样是无法被使用的)
show

# 新节点创建分组(新建后再show可以看到分组,但已有表不会自动关联这部分节点)
CREATE NODEGROUP 3,4

# 数据分布情况(看到新增节点没有应用0%)
ALL REPORT MEMORY

# 进入mysql客户端,执行脚本,对已有表进行重新分区
ALTER TABLE test_alert ALGORITHM=INPLACE, REORGANIZE PARTITION

# 再次查看数据分布情况会看到新分区已经有使用了
# 通过sql可以看到分区情况,由原有2个分区变成了4个分区
select partition_name,table_rows from information_schema.PARTITIONS where table_name='test_alert'

继续测试,空表开始
       -> 批量插入1000条连续执行10次,行数据0.3k左右
       => ndbcluster:平均2s/1k条
       => 单机innodb 平均0.55s/1k条
    cluster写入明显地域innodb,这个差距随着node节点的增多而加大,两个节点1.5s左右,四个节点2s左右,可以看出分发数据牺牲了不少时间,不过这样的成绩,是能够接受的。

1w条数据量,继续写入
       -> 批量插入2000条连续执行10次,行数据0.3k左右
       => ndbcluster:平均3.5s/2k条
       => 单机innodb 平均1.6s/2k条

3w数据,继续写入
       -> 批量插入2000条连续执行50次,行数据0.3k左右
       => ndbcluster:平均3.4s/2k条
       => 单机innodb 平均1.6s/2k条

13w数据,继续写入
       -> 批量插入4000条连续执行20次,行数据0.3k左右
       => ndbcluster:平均7.47s/4k条
       => 单机innodb 平均3.6s/2k条
    此时批量数量的增加对性能提升已经没什么帮助了,接下来就稳定在3k条的批量测试。
顺便一提,此时数据量已经达到21w,此时innodb的count全表已经变慢,2s左右,而ndbcluster还在毫秒的零头,当然count本来就不是innodb的优势,不能说明什么。

21w数据下,再测试一下单条写入性能
       -> 连续插入1000条,行数据0.3k左右
       => ndbcluster:平均0.029s/条
       => 单机innodb 平均0.03s/条
    差别不大,在这个量级测试一下随机更新、删除操作效果与写入情况一致

21w数据,检索情况
    -> count全表

    => ndbcluster 0.003s
    => 单机innodb 2.370s

    -> count 主键范围,同数量级(>33333,<99999)
    => ndbcluster  0.062s
    => 单机innodb  0.790s

    -> count 无索引字段,同数量级(time_type = 21)
    => ndbcluster  0.045s = 7070
    => 单机innodb  2.376s = 6995

    -> count 无索引字段,同数量级(threshold >0)
    => ndbcluster  0.104s  = 105226
    => 单机innodb  2.350s = 105478
ndbcluster引擎count多种情况下表现都比较好

    -> 全表 limit 1000,100
    => ndbcluster 0.213s
    => 单机innodb 0.057s

    -> 全表 limit 9000,100
    => ndbcluster 1.501s
    => 单机innodb 0.135s

    -> limit 1000,10 检索无索引字段(time_type = 21)
    => ndbcluster  0.190s 
    => 单机innodb  0.324s
limit情况一致,越靠后越慢,innodb表现无条件时表现较好,有条件时略差

    -> 随机主键检索
    => ndbcluster 0.003s
    => 单机innodb 0.003s
基本没有差别

    -> 常用场景1,检索+倒序+分页 ( select * from test_alert where threshold >0 order by msg_publish_time desc limit 20,20)
    => ndbcluster 0.292s
    => 单机innodb 2.383s

    -> 常用场景1,检索+正序+分页 (select * from test_alert where time_type = 13 order by msg_publish_time asc limit 20,20)
    => ndbcluster 0.159s
    => 单机innodb 2.581s
    ndbcluster优势较明显

开始加索引

  ALTER TABLE `test_alert` ADD INDEX `ix_t_ptime` (`msg_publish_time`) ;
  ALTER TABLE `test_alert` ADD INDEX `ix_t_threshold` (`threshold`) ;
  ALTER TABLE `test_alert` ADD INDEX `ix_t_ttype` (`time_type`) ;
  => cluster平均索引时间是0.5s
  => innodb平均索引时间是2.5s

再测试一下常用场景

    -> 常用场景1,检索+倒序+分页 (字段均有索引)
    => ndbcluster 0.022s
    => 单机innodb 0.065ss

    -> 常用场景1,检索+正序+分页 (字段均有索引)
    => ndbcluster 0.085s
    => 单机innodb 0.061s
    索引后差距不大了

索引后写入测试       
       -> 连续单条插入1000条,行数据0.3k左右
       => ndbcluster:平均0.029s/条
       => 单机innodb 平均0.026s/条
    索引前后区别不大

 

把数据量提到100w

此时内存占用情况
mysql-cluster7.6.8应用测试,对比单机innodb_第3张图片

调整DataMemory(MB)=1024,IndexMemory(MB)=96

此时空间占用情况变为:
mysql-cluster7.6.8应用测试,对比单机innodb_第4张图片
由此粗略估算,1G内存大概可存5百万数据,数据库服务器内存32G~128G较为常见,按64G分配50G计算,可存2.5亿行数据。
(仅做参考,实际内存消耗会受数据size、字段类型blob或text、索引数量等综合因素影响。测试表为磁盘存储模式,如果是内存表则消耗加倍)

再测试读写性能,结果并没有太大变化。

在测试检索性能时,上面测试过的结果均没有太大变化。

在百万级数据行做字符串like检索时,ndbcluster23.507s,innodb9.617s完成,不可思议,不同字段效果不同,估计与字段定长有关。
 

总结:

ndbcluster在count上的表现碾压innodb,但单机表引擎更换为MyISAM后,这个优势就没有了。

ndbcluster的定位是高可用,主要实现自动分片、分布式存储、跨节点备份等功能。

作为应用端,比较关注的特性cluster都有所体现:
服务器横向扩展能力,突破单机存储瓶颈。cluster较好的完成了这个任务,可以动态调整数据节点。
服务器负载能力。cluster提供了多sql节点平衡负载。
数据容灾,硬件损坏造成数据丢失问题。通过跨节点备份最大降低数据丢失概率。
高可用,个别服务异常,通过manager监听服务自动切换,manager多节点互相监听
客户端无感,不必大量修改sql即可支持。

单讲每个特性都有相应代替方案,比入主从复制、读写分离、分库分表、增量备份、keepalivevip漂移等。
mysqlcluster虽然较为全面,但总觉得力量不足,再三考虑后仍然放弃了投入生产

最初考虑mysqlcluster主要从横向扩展方面,但综合考虑内存与性能方面的代价(还有许多不确定因素),还是不太适合当前的场景,当前对高可用需求不大,事物要求不高可用MyISAM引擎,容灾能力通过主从复制及增量备份代替,磁盘问题采用多磁盘多分区方式过渡,如果数据量更大时再做其它考虑。

 

你可能感兴趣的:(Linux笔记,数据库)