当前位置: 首页 > 科技观察

如何在MySQL中实现每秒570,000次写入?

时间:2023-03-19 23:25:24 科技观察

1。需求朋友接到一个大数据平台的需求,收到20亿+的数据写入,需要快速加载到MySQL中,用于第二天的业务展示。2、实现重解析对于20亿的单表,在MySQL运维中,目前涉及的比较少,基本没有经验,但是对于InnoDB单表Insert,如果内存大于数据,它可以保持在100,000-150,000行写入。但是很多时候我们接受的项目还是数据多于内存。这里我们使用XeLabsTokuDB来做一个测试。3.XeLabsTokuDB介绍项目地址:https://github.com/XeLabs/tokudb相比官方TokuDB优化:内置jemalloc内存分配,引入更多内置TokuDB性能指标支持Xtrabackup备份引入ZSTD压缩算法支持TokuDB的binlog_group_commitFeature4.测试表TokuDB核心配置:loose_tokudb_cache_size=4Gloose_tokudb_directio=ONloose_tokudb_fsync_log_period=1000tokudb_commit_sync=0表结构CREATETABLE`user_summary`(`user_id`bigint(20)unsignedNOTNULLCOMMENT'用户id/手机号'charNCOMMENT',`5LDEVAR`,`weight`var`和码体重(KG)',`level`varchar(20)DEFAULTNULLCOMMENT'体重',`beat_rate`varchar(12)DEFAULTNULLCOMMENT'拍率',`level_num`int(10)DEFAULTNULLCOMMENT'人数同吨位',UNIQUEKEY`u_user_id`(`user_id`))ENGINE=TokuDBDEFAULTCHARSET=utf8使用loaddata写入数据root@localhost[zst]>LOADDATAINFILE'/u01/work/134-136.txt'\INTOTABLEuser_summary(user_id,weight,level,beat_rate,level_num);QueryOK,200000000rowsaffected(5min48.30sec)Records:200000000Deleted:0Skipped:0Warnings:0计算每秒写入速度:root@localhost[zst]>select200000000/(5*60+48.30);+----------------------+|200000000/(5*60+48.30)|+--------------------+|574217.6285|+------------------------+1rowinset(0.00sec)文件大小:-rw-r--r--1rootroot8.5GNovember2520:05134-136.txt-rw-r-----1mysqlmysql8.6KNovember2520:44user_summary.frm-rw-r-----1mysqlmysql3.5GNovember2520:51user_summary_main_229_1_1d_B_0.tokudb实际文件8.5G,写入TokuDB大小3.5G,仅接近20亿数据压缩量的一半写。实际测试在58分钟多一点的时间内完成。它可以满足实际需要。另外对于磁盘IO比较好的机器(SSD盘,云上的云盘),如果内存和数据差不多,这个级别的数据量测试需要在Innodb中添加自增列,3分钟内可以完成还有一点要完成。从实战来看,InnoDB和TokuDB写入相同的数据,InnoDB比TokuDB耗时大约3-4倍。文件大小不同,同样是20亿数据:-rw-r-----1mysqlmysql35GNovember2523:29user2_main_26a_1_1d_B_0.tokudb-rw-r-----1mysqlmysql176GNovember2603:32user5.ibd文件大小是5倍尺寸差异。测试结论:在8核8G内存、500G高速云盘环境的云环境下使用TokuDB,多次测试轻松达到每秒57万次写入。另外测试几个场景供大家参考:如果在TokuDB中使用自增主键,主键没有任何价值,这样MySQL内部写入速度会明显下降,也会写入2亿条数据,自建主键:root@localhost[zst]>CREATETABLE`user3`(->`user_id`bigint(20)unsignedNOTNULLCOMMENT'用户id/手机号',->`weight`varchar(5)DEFAULTNULLCOMMENT'和码重(KG)',->`level`varchar(20)DEFAULTNULLCOMMENT'重量级',->`beat_rate`varchar(12)DEFAULTNULLCOMMENT'拍率',->`level_num`int(10)DEFAULTNULLCOMMENT'吨位相同的人数',->`id`bigint(20)NOTNULLAUTO_INCREMENT,->PRIMARYKEY(`id`),->UNIQUEKEY`u_user_id`(`user_id`)->)ENGINE=TokuDB;QueryOK,0rowsaffected(0.03sec)root@localhost[zst]>LOADDATAINFILE'/u01/work/134-136.txt'INTOTABLEuser3(user_id,weight,level,beat_rate,level_num);QueryOK,200000000rowsaffected(22min43.62sec)Records:200000000Deleted:0Skipped:0警告:0相同的数据写在主键自增无值时生成,无法使用TokuDB的Bulkloader数据特性,相当于转为单Insert实现,所以效果太慢。关于TokuDBBulkLoader的前提要求,这张表是空表,也可以用于自增列,比如自增列有值时。建议在实际使用中,如果自增列有值,可以考虑去掉自增属性,改为唯一索引,减少自增的一些处理逻辑,让TokuDB运行起来快点。另外在BulkLoader处理中为了追求更快的写入,压缩也不是很好。关于TokuDBBulkLoader:https://github.com/percona/PerconaFT/wiki/TokuFT-Bulk-Loader五、测试环境说明测试使用CentOS7环境,编译XeLabsTokuDB版百度云地址:https://pan.百度.com/s/1qYRyH3I。