关于ElasticSearch与MySql的数据存储测试!
一直好奇存储大小相同的记录,es和mysql谁占用存储空间更大呢。虽然按道理来看应该是mysql,但一直没有亲自尝试,总还是心里感觉不那么踏实。
所以今天做一个测试,看看到底实际情况怎么样?
关于在二者的数据存储,有下面一个大概的说明,可能不够准确,但我只知道这么多:
1、ES先将数据存到内存,再通过队列的形式写到磁盘;虽然mysql也有内存模式,但是在大多数实际应用中我们仍然使用的传统模式,所以在并发写入方面,es要优于mysql。
2、ES存储的数据是经过压缩的。在实际测试中笔者发现6千条记录并不比5千条记录所占用的磁盘空间大。
3、关于mysql,每条索引的长度是和你创建列的时候制定的长度相同的。比如你创建varchar(100),当你在该列上创建索引,那么索引的长度则是102字节,因为长度超过64字节则会额外增加2字节记录索引的长度。
4、在这个测试中es未做分词,仅用于数据存储。
测试机硬件配置:
CPU |
I7 8核心 |
内存 |
12G |
硬盘 |
320G |
网络 |
局域网 |
|
|
ES索引配置:5个主分片,未添加复制分片。Type结构如下:
字段 |
类型 |
分词 |
备注 |
id |
string |
否 |
|
createTimeYmd |
date |
否 |
创建日期yyyy-mm-dd格式 |
createTime |
date |
否 |
创建时间yyyy-mm-dd hh:mi:ss格式 |
createName |
string |
否 |
|
xmlContent |
string |
否 |
申报表xml报文,本次测试中使用的xml报文为30kb的xml结构体。约等于2.8w个字符长度。 |
refKey |
string |
否 |
业务关联字段(模拟) |
mysql数据表的结构与es中type的结构相同,详细如下:
字段 |
类型 |
主键 |
备注 |
id |
long |
是 |
自增 |
createTimeYmd |
date |
|
创建日期yyyy-mm-dd格式 |
createTime |
date |
|
创建时间yyyy-mm-dd hh:mi:ss格式 |
createName |
varchar(10) |
|
|
xmlContent |
text |
|
申报表xml报文,本次测试中使用的xml报文为30kb的xml结构体。约等于2.8w个字符长度。 |
refKey |
varchar(10) |
|
业务关联字段(模拟) |
以下为es记录数与物理文件列表:
记录条数 单位:行 |
es数据文件(物理存储空间) |
mysql数据文件(物理存储空间) |
5000 |
21.8M |
183.51M |
15000 |
47.9M |
550.51M |
65000 |
257M |
2386M |
18w |
4.02GB |
对比鲜明,不忍继续 |
26.8w |
7.85GB |
|
677621 |
27.5GB |
从以上数据指标可以看出,ES在做存储的时候针对数据是做了压缩的。根据其规律可以推测出1000W行这样的记录,其存储空间约为500GB。1亿条记录,其主分片存储空间约为5T。
在5000至6.5w行数据的写入过程中,es与mysql完成写入的时间都在可接受的范围内,耗时并不长。(ps:mysql使用单线程for循环的方式插入数据;es前6.5w行记录使用单线程循环插入,后面数据过多,使用8个线程,循环插入。)
由于对比过于鲜明,相同数据量的情况下mysql占用的空间明显比es大很多,在插入6.5W行数据后就没再继续做插入测试。
在添加数据过程中,笔者尝试边写入边查询。使用refKey做为条件进行随机查询,值得一提的是在6.5万行记录中查询一条记录所耗时间不足3秒;而mysql,在边写入边查询的时候(特别是循环暴力写入),其查询几乎处于停滞状态。
在添加操作结束后,笔者随机做了一下查询操作,如果使用主键mysql查询能够很快得到结果,如果使用非主键----refKey做查询,mysql要在7,8秒左右才能返回结果,而es查询相同条件的数据,仅需要2秒不足,且es里面的总数据量在60w+,比mysql的数据总量要大很多。
做此对比的目的不是说es就比mysql好用。二者各有所长,要按使用场景,按需选用。
以上为es与mysql存储数据的对比结果。测试过程中使数据在附件中列出。如果没有,可能是我忘了, 如果有人需要,可提醒我上传。