什么是SPDK,以及什么场景需要它
什么是SPDK,以及什么場景需要它
- 1. 前言
- 2. 什么是spdk
- 3. spdk的設計理念
- 3. 使用spdk加速NVMe存儲
- 4. spdk bdev
- 5. spdk應用場景
- 6. 總結
- 7. 參考鏈接
1. 前言
有關spdk網上已經有了很多文章,筆者只是想結合自己日常工作對spdk的理解,闡述為什么是spdk是一個高性能的解決方案,以及什么場景適合用spdk。本文不會特別深入某個具體技術細節,有關具體的技術實現,筆者會放在文末的參考連接中。
2. 什么是spdk
首先要明確spdk是一個框架,而不是一個分布式系統,spdk的基石(官網用了bedrock 這個詞)是用戶態(user space)、輪詢(polled-mode)、異步(asynchronous)、無鎖(lockless)的NVMe驅動,其提供了零拷貝、高并發直接從用戶態訪問ssd的特性。其最初的目的是為了優化塊存儲落盤。但隨著spdk的持續演進,大家發現spdk可以優化存儲軟件棧的各個方面。
很多分布式存儲系統都在思考如何吸納spdk框架,或是采用spdk代表的高性能存儲技術,來優化整條IO鏈路。
3. spdk的設計理念
spdk主要通過引入以下技術,實現其高性能方案。
- spdk設計的主要目標之一就隨著使用硬件(e.g. SSD,NIC,CPU)的增多而獲得性能的線性提升,為了達到這目的,spdk的設計者就必須消除使用更多的系統資源帶來的overhead,如:更多的線程、進程間通信,訪問更多的存儲硬件、網卡帶來的性能損耗。
- 為了降低這種性能開銷,spdk引入了無鎖隊列,使用lock-free編程,從而避免鎖帶來的性能損耗。
- spdk的無鎖隊列主要依賴的dpdk的實現,其本質是使用cas(compare and swap)實現了多生產者多消費者FIFO隊列。有關無鎖隊列的實現可以看這篇文章
通俗的來講spdk運行時會占用滿指定的CPU core,其本質就是一個大的while死循環,占滿一個cpu core。去連續的跑用戶指定的poller,輪詢隊列、網絡接口等等。因此,spdk編程最基本的準則,就是避免在spdk核上出現進程上下文切換。其會打破spdk高性能框架,造成性能降低甚至不能工作。
進程上下文切換會因為很多原因導致,大致列舉如下,我們在spdk編程時切忌要避免。筆者就曾遇到因為spdk線程中一個不起眼的系統調用mmap進入了內核,導致整個spdk進程不可服務直到宕機。
- cpu時間片耗盡
- 進程在系統資源不足(比如內存不足)時,要等到資源滿足后才可以運行,這個時候進程也會被掛起,并由系統調度其他進程運行。
- 進程主動調用sleep等函數讓出cpu使用權。
- 當有優先級更高的進程運行時,為了保證高優先級進程的運行,當前進程會被掛起,由高優先級進程來運行。
- 硬件中斷會導致CPU上的進程被掛起,轉而執行內核的中斷服務程序。
3. 使用spdk加速NVMe存儲
spdk希望通過在用戶態直接訪問NVMe SSD,而不經過kernel nvme 驅動(bypass kernel)。
spdk將NVMe SSD從內核驅動解綁,再綁定到vfio或者uio驅動上。雖然這兩個啟動本身不會對nvme設備做任何初始化操作。但它給了SPDK直接訪問nvme設備的能力,后續的初始化和下發命令都由spdk負責。所以spdk訪問NVMe SSD的調用基本上都是和nvme命令對應的,如admin cmd spdk_nvme_ctrlr_cmd_set_feature、spdk_nvme_ctrlr_cmd_get_log_page,和io cmd spdk_nvme_ctrlr_alloc_io_qpair、spdk_nvme_ns_cmd_read等等。當然,iouring已經和這里的io cmd有點像了:)
4. spdk bdev
spdk在上述加速訪問NVMe存儲的基礎上,提供了塊設備(bdev)的軟件棧,這個塊設備并不是linux系統中的塊設備,spdk中的塊設備只是軟件抽象出的接口層。
spdk已經提供了各種bdev,滿足不同的后端存儲方式、測試需求。如NVMe (NVMe bdev既有NVMe物理盤,也包括NVMeof)、內存(malloc bdev)、不落盤直接返回(null bdev)等等。用戶也可以自定義自己的bdev,一個很常見的使用spdk的方式是,用戶定義自己的bdev,用以訪問自己的分布式存儲集群。
spdk通過bdev接口層,統一了塊設備的調用方法,使用者只要調用不同的rpc將不同的塊設備加到spdk進程中,就可以使用各種bdev,而不同修改代碼。并且用戶增加自己的bdev也很簡單,這極大的拓展了spdk的適用場景。
講到這里,各位同學應該明白了,spdk目前的的應用場景主要是針對塊存儲,可以說塊存儲的整個存儲的基石,再其之上我們又構建了各種文件存儲、對象存儲、表格存儲、數據庫等等,我們可以如各種云原生數據庫一樣將上層的分布式系統直接構建在分布式塊存儲、對象存儲之上,也可以將其他存儲需要管理的元數據、索引下推到塊層,直接用spdk優化上層存儲,比如目前的塊存儲使用lba作為索引粒度管控,我們可以將索引變為文件/對象,在其之上構建文件/對象存儲系統。
5. spdk應用場景
spdk最直接的使用方式是作為存儲引擎加速訪問NVMe SSD。在此之上spdk又抽象了bdev層,各種業務通過綁定bdev,可以將塊存儲設備通過某種方式暴露給用戶,這就是我們下面要講到的各種應用場景。
企業使用塊存儲的目的,就是將后端存儲(可以是本地盤,也可以是分布式存儲集群)暴露給用戶,它的實現形式如公有云、私有云等等我們暫且不討論。單就表現方式來講,我們有很多方法將這個塊設備暴露給用戶,筆者主要接觸到如下幾種:
前兩種方式,spdk都提供有對應的后端驅動,如iSCSI target,NVMe-oF target,vhost target等。第三類方式不同廠商具體實現方式有所不同,未必開源。我們使用spdk作為這些后端驅動,接收客戶端的IO并進行處理,其好處是可以利用到spdk高性能存儲框架,也就是之前提到的user space,polled-mode,asynchronous,lockless。spdk官網有很多測試文檔介紹使用spdk和其他開源實現的性能比較,還是較為可觀的。
6. 總結
筆者已經使用spdk兩年了,總體來說還是較為滿意的,spdk社區提供了各種手段供大家交流,spdk的中國團隊也經常出一些技術文章、技術視頻的等等。并且spdk一路走來,一直在吸納、支持各種軟件、硬件新特性。我們通過學習spdk,可以接觸到存儲技術棧的各個方面。所以我認為作為一個存儲人,無論是否在工作中使用到spdk,都必須了解spdk背后的各種高性能存儲技術。
7. 參考鏈接
總結
以上是生活随笔為你收集整理的什么是SPDK,以及什么场景需要它的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: raft引入no-op解决了什么问题
- 下一篇: 一致性协议raft详解(一):raft整