只參加了初賽,複賽沒時間參加。最終初賽結果top 59/1653,第一次參加這種性能比賽,收穫頗豐。html
比賽整體分紅了初賽和複賽兩個階段,總體要求實現一個簡化、高效的 kv 存儲引擎
初賽要求支持 Write、Read 接口。
複賽在初賽題目基礎上,還須要額外實現一個 Range 接口。
程序評測邏輯 分爲2個階段:
1)Recover 正確性評測:
此階段評測程序會併發寫入特定數據(key 8B、value 4KB)同時進行任意次 kill -9 來模擬進程意外退出(參賽引擎須要保證進程意外退出時數據持久化不丟失),接着從新打開 DB,調用 Read、Range 接口來進行正確性校驗java
2)性能評測
隨機寫入:64 個線程併發隨機寫入,每一個線程使用 Write 各寫 100 萬次隨機數據(key 8B、value 4KB)
隨機讀取:64 個線程併發隨機讀取,每一個線程各使用 Read 讀取 100 萬次隨機數據
順序讀取:64 個線程併發順序讀取,每一個線程各使用 Range 有序(增序)遍歷全量數據 2 次 注: 2.2 階段會對全部讀取的 kv 校驗是否匹配,如不經過則終止,評測失敗; 2.3 階段除了對迭代出來每條的 kv校 驗是否匹配外,還會額外校驗是否嚴格字典序遞增,如不經過則終止,評測失敗。git
第一次參加這種性能大賽,想着是先實現幾種基本的kv模型,再調優。因而通過網上資料調研,先初步實現了幾種基本的存儲模型:BitCask、LSM。這時key,value是存在一塊兒的,單獨維護了索引文件,LSM樹中採用超過閾值則進行compaction操做,即k路歸併操做。github
因而早早地寫好了第一天開評測就線上測試,結果老是超時(官方限定一小時內沒跑完則超時)。因而就沉迷優化代碼,去掉重量級鎖,改成輕量級鎖,線下使用JProfile等工具進行性能調優。奈何不管如何調優,線上老是超時,偶爾還莫名其妙的OOM。通過幾天debug,也沒有任何轉機。安全
就在快要放棄時,通過一名大神提點,忽然發現可能根本是個人方案就有問題。
才發現本身忽略了比賽很重要的一個前提:存儲設備是SSD!而不是通常的磁盤。
因而再次調研,發現一篇論文:WiscKey: Separating Keys from Values in SSD-conscious Storage 是專門針對LSM在SSD上作的優化。核心思想就是將key 、value分開存儲多線程
而且瞭解到,本次比賽的 key 共計 6400w,分佈比較均勻。因而通過和隊友的討論,以爲能夠將key、value分開存,這能夠解決寫放大問題,可是線程競爭呢?64個線程,實際線下測的時候每次併發跑的最多50多個,總會有好幾個線程被阻塞。因而查閱資料,發現可使用「數據分桶」的思想,併發
因而,咱們趕忙從新實現了一版BucketDB,按照分桶的思想,進行新的一輪測試,終於,此次有了姓名!函數
數據分桶的好處,能夠大大減小順序讀寫的鎖衝突,而 key 的分佈均勻這一特性,啓發咱們在作數據分區時,能夠按照 key 的位進行設計hash函數,將高几位相同的key都分進一個桶。工具
以後想到了幾個優化思路:post
線上錯誤日誌:內存映射文件時寫入失敗
後來發現是元空間的鍋!jdk1.8裏的metaspace!
元空間並不在虛擬機中,而是使用直接內存,
因而還須要設置一個Metaspace參數,以防止直接內存爆掉!
-XX:MaxMetaspaceSize=300m
另外,優化了整個程序的內存使用 => 隨着整個程序的運行,內存佔用愈來愈大,顯然是不少對象沒有回收 => 優化程序,經過將沒必要要的引用設爲null,循環內不建立對象
線上超時問題,一是LSM自己寫放大明顯;二是多線程競爭激烈,線程切換過多,致使寫入性能急劇降低。
https://github.com/abbshr/abbshr.github.io/issues/58
http://www.cnblogs.com/haippy/archive/2011/12/04/2276064.html
https://raoxiaoman.github.io/2018/04/08/wisckey%E9%98%85%E8%AF%BB/. LSM-Tree存在的問題
https://colobu.com/2017/10/11/badger-a-performant-k-v-store/
http://www.javashuo.com/article/p-eysmnacc-gk.html
https://zhuanlan.zhihu.com/p/38810568
http://blog.jobbole.com/69969/
https://www.zhihu.com/question/31024021
https://juejin.im/post/5ba9f9d7f265da0afd4b3de7 探究SSD寫放大的成因與解決思路
http://codecapsule.com/2014/10/18/implementing-a-key-value-store-part-7-optimizing-data-structures-for-ssds/