JIMDB:一個大規模分布式內存存儲的演進之路

jopen 9年前發布 | 26K 次閱讀 JIMDB
 

寫在前面: Redis 是一個C語言編寫的開源、支持網絡、基于內存、鍵值對存儲、可持久化的高性能NoSQL數據庫,同時提供多種語言的API,目前最新版本為 3.0.5 。由于性能優異,已被國內外 眾多公司采用構建緩存集群 。其中,京東對Redis的應用實踐可圈可點。

在2014年的 QCon上海 大會上,京東云平臺首席架構師劉海鋒介紹了 京東分布式內存存儲平臺(RAM store platform) 。經過兩年多的演進,這套系統已經支撐起京東幾乎所有的在線業務。近日,InfoQ采訪了劉海鋒,再探這個分布式內存存儲平臺的全貌。以下是采訪實錄:

InfoQ:你能簡單介紹一下JIMDB這兩年來的研發過程嗎?

劉海峰:JIMDB是一個以內存為中心的鍵值數據庫,目前在我們京東多個數據中心部署了幾千臺機器,支撐了京東幾乎所有的在線業務。JIMDB的研發是一個逐步演進的過程,最初是從Redis改進而來,現在的數據模型是兼容但不僅限于Redis,可以理解為Redis的一個超集。JIMDB在京東的應用也不限于緩存,我們很多業務線已經把它當成唯一的存儲。

具體來說,研發過程經歷了三個階段:

  • 第一個階段是從2013年底開始。當時我們在使用Redis時遇到了一些問題,為了解決這些問題,我們把Redis這個優秀的單機軟件變成一個健壯的分布式系統。比如我們要做故障的手動、自動切換;要實現橫向擴展,動態分片并且不能影響網絡流量;要實現靈活的異步復制、同步復制。雖然每個實例仍然是單個的Redis,但整個的集群能夠實現故障的切換、橫向的擴展和比較靈活的復制。

  • 第二個階段從2014年下半年開始。用一句話來概括這個階段就是把JIMDB變成了一個完全托管、自管理、自運維的存儲服務。因為Redis的引擎比較簡單,為了實現這個目標,我們重寫了整個內存存儲的引擎,使之可以支持更細粒度的分片;復制協議部分也作了改動,不但支持全量復制、增量復制,還支持了任意局部復制。例如,我們經常遇到某個分片上的熱數據過載的問題,這時候的解決方案是把這部分數據復制到其他的實例上,從而分散流量,這樣我們就實現了動態的分裂、合并。在運維管理上我們引入了Docker,部署環節實現了整體的調度。

  • 第三個階段在2015年上半年啟動規劃,目前這個階段還在進行中。我們已經把很多實現陸續推到了線上。即,不僅僅支持原來的哈希分片和原有的數據類型,我們還實現了在內存中支持畢加樹、支持按范圍的劃分、支持排序的遍歷、復制協議也更健壯、更可靠,等等。第三階段實現的特性將比Redis更加強大。當一個分布式存儲支持按范圍分片和復制的時候,這個系統無疑是更健壯和更可靠的。當然,這個階段也存在很多的挑戰,例如,哈希的分片相對來說比較簡單,但我們要實現按范圍、跨數據中心的異步和同步復制時,這個挑戰就大的多了。

縱觀這兩年的發展,JIMDB從最初的幾臺服務器到現在的幾千臺、從單機Redis系統到自管理的分布式存儲系統、用戶只需要一個認證授權即可使用、支持京東線上一千多個業務(集群),是一個不斷挑戰的過程。

InfoQ:市面上已經有了大量的鍵值對存儲數據庫,并且已經在大公司的生產環境投入使用。為什么京東還要開發JIMDB?

劉海峰:這更多的是業務的需求。公司原來的存儲應用百花齊放,有人用Redis、有人用MongoDB、有人用memcached等等。但現在的情況是,數據庫用MySQL比較多;NoSQL幾乎99%的都在用JIMDB。原因在于JIMDB有人維護、自管理、性能穩定,儼然已成為京東內部壟斷性的應用。但在項目開始的時候我們也沒想到會變成今天的規模,隨著業務的發展,JIMDB一步一步演進成了今天的樣子。

InfoQ:JIMDB在京東的主要應用場景是哪些業務領域?在這些應用場景里,跟其他內存存儲相比JIMDB有哪些優勢?

劉海峰:目前JIMDB的應用場景十分廣泛。比如,現在依然有很多同事把JIMDB當Redis來用,很多人拿來當緩存用,也有很多人把JIMDB當唯一存儲在用,用法不一而足。甚至,很多離線計算MapReduce的結果也直接存在JIMDB里;對京東的訪問用戶來說,大家看到的商品詳情整個頁面的所有元素、第三方show的廣告、搜索推薦的結果等等,都是存在JIMDB里面。我們支撐了無線端、PC端很多業務。但總的來說,目前用量最大的業務是搜索和推薦的集群,另外單品頁的用量也很大。因此這個系統的壓力也很大。

跟其他內存存儲相比,首先這個系統是從Redis演進過來的,Redis有的功能我都有,但是JIMDB在很多方面都比Redis更健壯、更穩定。其次,從Redis的視角來說,這是一個經過大規模生產環境驗證的、更好的Redis。目前我們有六、七個人在維護這個系統。

InfoQ:對冷熱數據的處理以及數據持久化JIMDB是怎么做的?在算法和數據結構方面JIMDB做了哪些優化設計?

劉海峰:持久化還是采用經典的方式——記日志、定期做快照。雖然這是一個很簡單的方式,但是十分的有效。對于可預測的熱數據我們會預先做分片,尤其是秒殺活動的內容;而對瞬時的熱數據做動態調整是JIMDB最優先的特性實現,這跟我們電商的特性相關。目前京東的老機房大量部署了JIMDB,新機房也部署了很多。

算法和數據結構方面,剛才已經舉過一個例子就是畢加樹。我們實現了KV的有序排列和按任意范圍的分割、復制。這是我們新加的數據類型,其他的支持已經十分強有力了。

InfoQ:據我所知Redis所在機器物理內存使用率并不高(貌似沒有超過實際內存總量的60%)。針對京東這么大規模的在線存儲,內存管理方面JIMDB是怎么做的?

劉海峰:這一方面主要做的工作是內存分配器的優化。Redis的內存分配器是 jemalloc ,我們依然沿用了jemalloc,但是我們作了很多優化。此外,我們對比較大的Value做了特殊處理,比如我們不讓大Value的存儲占據內存,而把它寫到磁盤中去。但是很多人會問SSD的問題,為什么不采用混合存儲的架構?

其實在2014年的時候我們專門在線上測試過這個方案,當時大概對10%的集群采用了混合存儲的方案。經過一段時間的測試發現:

  • 首先,雖然SSD的成本有一定的優勢,但實施工程是有成本的。基于磁盤去寫一個有豐富類型的鍵值數據庫其實是比較復雜的,即使是簡單的鍵值都比較復雜,在遇到Map、List、畢加樹等等,用磁盤的方式實現起來其實更為負責、成本更高。也就是說,其實現和維護的成本太高,并且性能也不占優,整體工程成本遠遠超過內存存儲。

  • 第二個原因在于,內存的價格在逐漸降低,我們是能承受這個成本的。目前我們使用的內存也越來越大,預計明年我們將在單機上使用1T的內存。

  • 第三個原因是系統架構方面的考慮。我們的數據中心有很多的機器,很多應用服務器和私有云服務器多數時候的內存利用率并不高,我們可以利用這些機器的資源做JIMDB的動態資源池,只需要在相應的機器上部署一個JIMDB的程序就好。這也極大地提高了整個數據中心的資源利用率。

基于以上三點考慮,我們選擇用內存做存儲。隨著京東業務的發展,未來1~2年我們JIMDB的規模將達到1萬臺機器,當然,這1萬臺機器并不是專用的,而是JIMDB在整個數據中心的部署量。

InfoQ:你能談談JIMDB在“雙11”大考中的表現嗎?

劉海峰:JIMDB在“雙11”的表現很好,系統穩定,性能平穩。我們的新機房啟用了大量萬兆網卡,以前千兆網卡被打滿的情況終于得到緩解。但任何系統都不可能沒有任何瑕疵,現在看來JIMDB的問題更多的不是技術性的,而是系統到了一定量級怎么去運維,尤其是系統預警和運維操作流程方面的工作需要加強。隨著公司業務的發展,運維正變得越來越重要。

我們花了很多精力來做監控與運維。JIMDB核心的部分是一個個兼容Redis協議的Server,除了網絡部分,我們幾乎重寫了整個存儲引擎。還是拿一個具體的應用場景來說吧,假設我一臺機器上跑了15個實例,但是發現其中一個實例的流量極大,把其他實例的帶寬都給占了。這個時候我需要對這個有問題的實例進行分裂和遷移。但是遷移的時候存在一個問題,由于進出流量都很大,遷移有可能是遷不動的。這個時候我們有一個限流措施,保證在不影響其他實例帶寬的情況下把有問題的實例遷走。

InfoQ:你怎么看待JIMDB未來的發展趨勢?或者,你能否談一下內存云存儲(RAMCloud)的未來?

劉海峰:我非常堅信的一點是, 內存是存儲的未來 ,特別是對一些有結構化的數據來說。隨著內存成本的降低,以及在內存上實現存儲的簡潔和高效,這個趨勢勢不可擋。而且我認為JIMDB這兩年做的工作是一種更務實的RAMCloud實現,它是業務驅動的、經過大規模生產環境驗證的。

未來隨著系統的發展,在功能上我們會以內存為中心,做有序的、KeyValue的、豐富數據類型的大表支持。JIMDB未來有可能會加入一些SQL的支持。目前要先把規模、穩定和運維做好。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!