一直好奇存儲大小相同的記錄,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存儲數據的對比結果。測試過程中使數據在附件中列出。如果沒有,可能是我忘了, 如果有人需要,可提醒我上傳。