滴滴Ceph分布式存儲系統優化之鎖優化

摘自:https://mp.weixin.qq.com/s/oWujGOLLGItu1Bv5AuO0-A

?2020-09-02 21:45

0.引言

????????Ceph是國際知名的開源分布式存儲系統,在工業界和學術界都有著重要的影響。Ceph的架構和算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存儲系統,此外,Ceph也廣泛應用在文件、對象等存儲領域。Ceph在滴滴也支撐了很多關鍵業務的運行。在Ceph的大規模部署和使用過程中,我們發現了Ceph的一些性能問題。圍繞Ceph的性能優化,我們做了很多深入細致的工作。這篇文章主要介紹我們通過調試分析發現的Ceph在鎖方面存在的問題和我們的優化方法。

1.?背景

????????在支撐一些延遲敏感的在線應用過程中,我們發現Ceph的尾延遲較差,當應用并發負載較高時,Ceph很容易出現延遲的毛刺,對延遲敏感的應用造成超時甚至崩潰。我們對Ceph的尾延遲問題進行了深入細致的分析和優化。造成尾延遲的一個重要原因就是代碼中鎖的使用問題,下面根據鎖問題的類型分別介紹我們的優化工作。本文假設讀者已熟悉Ceph的基本讀寫代碼流程,代碼的版本為Luminous。

2.?持鎖時間過長

2.1 異步讀優化

????????Ceph的osd處理客戶端請求的線程池為osd_op_tp,在處理操作請求的時候,線程會先鎖住操作對應pg的lock。其中,處理對象讀請求的代碼如下圖所示,在鎖住對象所屬pg的lock后,對于最常用的多副本存儲方式,線程會同步進行讀操作,直到給客戶端發送返回的數據后,才會釋放pg lock。

????????在進行讀操作時,如果數據沒有命中page cache而需要從磁盤讀,是一個耗時的操作,并且pg lock是一個相對粗粒度的鎖,在pg lock持有期間,其它同屬一個pg的對象的讀寫操作都會在加鎖上等待,增大了讀寫延遲,降低了吞吐率。同步讀的另一個缺點是讀操作沒有參與流量控制。

圖片

????????我們對線上集群日志的分析也驗證了上述問題,例如,一個日志片段如下圖所示,圖中列舉了兩個op的詳細耗時信息,這兩個op均為同一個osd的線程所執行,且操作的是同一個pg的對象。根據時間順序,第一個op為read,總耗時為56ms。第二個op為write,總耗時為69ms。圖中信息顯示,第二個op處理的一個中間過程,即副本寫的完成消息在處理之前,在osd請求隊列中等待了36ms。結合上圖的代碼可以知道,這36ms都是耗在等待pg lock上,因為前一個read操作持有pg lock,而兩個對象屬于相同pg。????????

圖片

????????我們的優化如下圖所示,我們創建了獨立的讀線程,負責處理讀請求,osd_op_tp線程只需將讀請求提交到讀線程的隊列即可返回解鎖,大大減少了pg lock的持有時間。讀線程完成磁盤讀之后,將結果放到finisher線程的隊列,finisher線程重新申請pg lock后負責后續處理,這樣將耗時的磁盤訪問放在了不持有pg lock的流程中,結合我們在流量控制所做的優化,讀寫操作可以在統一的框架下進行流量控制,從而精準控制磁盤的利用率,以免磁盤訪問擁塞造成尾延遲。

圖片

????????我們用fio進行了異步讀優化效果的測試,測試方法:對同一個pool的兩個rbd,一個做隨機讀,另一個同時做隨機寫操作,將pg number配置為1,這樣所有對象讀寫會落到同一個osd的同一個pg。異步讀優化后,隨機寫平均延遲下降了53%。下圖為某業務的filestore集群異步讀上線前后讀吞吐率的數據,箭頭所指為上線時間,可見上線之后,集群承載的讀操作的吞吐率增加了120%

圖片

????????上述優化在使用filestore存儲后端時取得了明顯的效果,但在使用bluestore存儲后端時,bluestore代碼中還存在持有pg粒度鎖同步讀的問題,具體見BlueStore::read的代碼。我們對bluestore的讀也進行了異步的優化,這里就不詳細介紹了。? ??

3.?鎖粒度過粗

3.1 object cache lock優化

????????Ceph在客戶端實現了一個基于內存的object cache,供rbd和cephfs使用。但cache只有一把大的互斥鎖,任何cache中對象的讀寫都需要先獲得這把鎖。在使用寫回模式時,cache flusher線程在寫回臟數據之前,也會鎖住這個鎖。這時對cache中緩存對象的讀寫都會因為獲取鎖而卡住,使讀寫延遲增加,限制了吞吐率。

????????我們實現了細粒度的對象粒度的鎖,在進行對象的讀寫操作時,只需獲取對應的對象鎖,無需獲取全局鎖。只有訪問全局數據結構時,才需要獲取全局鎖,大大增加了對象間操作的并行。并且對象鎖采用讀寫鎖,增加了同一對象上讀的并行。測試表明,高并發下rbd的吞吐率增加了超過20%

4.?不必要的鎖競爭

4.1減少pg lock競爭

????????Ceph的osd對客戶端請求的處理流程為,messenger線程收到請求后,將請求放入osd_op_tp線程池的緩存隊列。osd_op_tp線程池的線程從請求緩存隊列中出隊一個請求,然后根據該請求操作的對象對應的pg將請求放入一個與pg一一對應的pg slot隊列的尾部。然后獲取該pg的pg lock,從pg slot隊列首部出隊一個元素處理。

????????可見,如果osd_op_tp線程池的請求緩存隊列中連續兩個請求操作的對象屬于相同的pg,則一個osd_op_tp線程出隊前一個請求加入pg slot隊列后,獲取pg lock,從pg slot隊列首部出隊一個請求開始處理。另一個osd_op_tp線程從請求緩存隊列出隊第二個請求,因為兩個請求是對應相同的pg,則它會加入相同的pg slot隊列,然后,第二個線程在獲取pg lock時會阻塞。這降低了osd_op_tp線程池的吞吐率,增加了請求的延遲。

????????我們的優化方式是保證任意時刻每個pg slot隊列只有一個線程處理。因為在處理pg slot隊列中的請求之前需要獲取pg lock,因此同一個pg slot隊列的請求是無法并行處理的。我們在每個pg slot隊列增加一個標記,記錄當前正在處理該pg slot的請求的線程。當有線程正在處理一個pg slot的請求時,別的線程會跳過處理該pg slot,繼續從osd_op_tp線程池的請求緩存隊列出隊請求。

4.2 log lock優化

????????Ceph的日志系統實現是有一個全局的日志緩存隊列,由一個全局鎖保護,由專門的日志線程從日志緩存隊列中取日志打印。工作線程提交日志時,需要獲取全局鎖。日志線程在獲取日志打印之前,也需要獲取全局鎖,然后做一個交換將隊列中的日志交換到一個臨時隊列。另外,當日志緩存隊列長度超過閾值時,提交日志的工作線程需要睡眠等待日志線程打印一些日志后,再提交。鎖的爭搶和等待都增加了工作線程的延遲。

????????我們為每個日志提交線程引入一個線程局部日志緩存隊列,該隊列為經典的單生產者單消費者無鎖隊列。線程提交日志直接提交到自己的局部日志緩存隊列,該過程是無鎖的。只有隊列中的日志數超過閾值后,才會通知日志線程。日志線程也會定期輪詢各個日志提交線程的局部日志緩存隊列,打印一些日志,該過程也是無鎖的。通過上述優化,基本避免了日志提交過程中因為鎖競爭造成的等待,降低了日志的提交延遲。測試在高并發日志提交時,日志的提交延遲可降低接近90%

4.3 filestore apply lock優化

????????對于Ceph filestore存儲引擎,同一個pg的op需要串行apply。每個pg有一個OpSequencer(簡稱osr),用于控制apply順序,每個osr有一個apply lock以及一個op隊列。對于每個待apply的op,首先加入對應pg的osr的隊列,然后把osr加到filestore的負責apply的線程池op_tp的隊列,簡稱為apply隊列。op_tp線程從apply隊列中取出一個osr,加上它的apply lock,再從osr的隊列里取出一個op apply,邏輯代碼如下圖左所示。可見,每個op都會把其對應的osr加入到apply隊列一次。如果多個op是針對同一個pg的對象,則這個pg的osr可能多次加入到apply隊列。如果apply隊列中連續兩個osr是同一個pg的,也就是同一個osr,則前一個op被一個線程進行apply時,osr的apply lock已經加鎖,另一個線程會在該osr的apply lock上阻塞等待,降低了并發度。

圖片

????????這個問題也體現在日志中。一個線上集群日志片段如下圖,有兩個op_tp線程6700和5700,apply隊列里三個對象依次來自pg: 1.1833, 1.1833. 1.5f2。線程6700先拿到第一個對象進行apply, 線程5700拿第二個對象進行apply時卡在apply lock上,因為兩個對象都來自pg 1.1833,直到6700做完才開始apply。而6700拿到第三個對象,即1.5f2的對象進行apply即寫page cache只用了不到1ms,但實際apply延遲234ms,可見第三個對象在隊列里等待了233ms。如果5700不用等待apply lock,則第二和第三個對象的apply延遲可以大大縮短。

圖片

????????我們優化后的邏輯代碼如上圖右所示,同一個osr只加入apply隊列一次,取消apply lock,利用原子操作實現無鎖算法。上面的算法可以進一步優化,在將一個osr出隊之后,可以一次從它的隊列中取m(m>1)個op進行apply,在op apply完成階段,改為如果atomic::fetch_sub(osr->queue_length, m) > m,則將osr重新入隊以提高吞吐率。

????????我們用fio進行了apply lock優化效果測試,方法為建兩個pool,每個pool的pg number為1,每個pool一個rbd, ?對兩個rbd同時進行隨機寫的操作,一個pool寫入數據的量為31k*10k,另一個pool寫入數據的量為4k*100k, 衡量所有請求apply的總耗時。優化前總耗時434ks, 優化后總耗時45ks,減少89.6%

團隊介紹

????????滴滴云平臺事業群滴滴云存儲團隊原隸屬于滴滴基礎平臺部,現隸屬于新成立的滴滴云事業部。團隊承擔著公司在線非結構化存儲服務的研發,并參與運維工作。具體來說,團隊承擔了公司內外部業務的絕大部分的對象、塊、文件存儲需求,數據存儲量數十PB。團隊技術氛圍濃厚,同時具備良好的用戶服務意識,立足于用技術創造客戶價值,業務上追求極致。團隊對于分布式存儲、互聯網服務架構、Linux存儲棧有著深入的理解。

作者介紹

圖片

????????負責滴滴在線非結構化存儲研發,曾任國防科技大學計算機學院副研究員,教研室主任,天河云存儲負責人

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/40156.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/40156.shtml
英文地址,請注明出處:http://en.pswp.cn/news/40156.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Transformers架構系列---transformers庫的使用

Transformers最初是由Google發布的論文 Attention is All You Need (2017) 提出的一種新的深度學習網絡架構,這篇論文證明了序列模型(如 LSTM)可以完全被注意力機制取代,甚至可以獲得更好的性能。Transformers網絡結構自2017年提出之后僅僅一兩年的時間內就一直在NLP領域及…

Vue:使用Promise.all()方法并行執行多個請求

在Vue中,可以使用Promise.all()方法來并行執行多個請求。當需要同時執行多個異步請求時,可以將這些請求封裝為Promise對象并使用Promise.all()方法來執行它們。 示例1: 以下是一個示例代碼,展示了如何通過Promise.all()方法并行…

C語言——動態內存管理

動態內存管理詳解 前言:一、為什么存在動態內存分配二、動態內存函數2.1malloc函數2.2calloc函數2.3realloc函數2.4free函數 三、常見的動態內存錯誤3.1 對NULL指針解引用操作3.2 對動態開辟空間的越界訪問3.3 對非動態開辟內存使用free釋放3.4 使用free釋放動態開辟…

Unity UI內存泄漏優化

項目一運行,占用的內存越來越多,不會釋放,導致GC越來越頻繁,越來越慢,這些都是為什么呢,今天從UI方面談起。 首先讓我們來聊聊什么是內存泄漏呢? 一般來講內存泄漏就是指我們的應用向內存申請…

Rabbitmq消息不丟失

目錄 一、消息不丟失1.消息確認2.消息確認業務封裝2.1 發送確認消息測試2.2 消息發送失敗,設置重發機制 一、消息不丟失 消息的不丟失,在MQ角度考慮,一般有三種途徑: 1,生產者不丟數據 2,MQ服務器不丟數據…

設計HTML5列表和超鏈接

在網頁中,大部分信息都是列表結構,如菜單欄、圖文列表、分類導航、新聞列表、欄目列表等。HTML5定義了一套列表標簽,通過列表結構實現對網頁信息的合理排版。另外,網頁中還包含大量超鏈接,通過它實現網頁、位置的跳轉&…

C語言“牽手”微店商品詳情數據方法,微店商品詳情API接口申請指南

微店平臺的商品詳情通常包括以下信息: 商品名稱:展示商品的名稱,用于描述商品的特性和分類。 商品圖片:展示商品的圖片,可以有多張圖片以展示不同角度和細節。 商品價格:顯示商品的銷售價格,可…

nodejs服務后臺持續運行三種方法

nodejs服務后臺持續運行三種方法 一、利用 forever 推薦 forever是一個nodejs守護進程,完全由命令行操控。forever會監控nodejs服務,并在服務掛掉后進行重啟。 1、安裝 forever npm install forever -g 2、啟動服務 service forever start 3、使用…

小程序CSS button按鈕自定義高度之后不居中

問題&#xff1a; 按鈕設置高度后不居中 <view><button class"btn1" size"">Save</button> </view> page {font-size: 30rpx; }.btn1 {margin-top: 100rpx;height: 190rpx;background: linear-gradient(90deg, #FF8A06, #FF571…

Wi-Fi 安全在學校中的重要性

Wi-Fi 是教育機構的基礎設施&#xff0c;從在線家庭作業門戶到虛擬教師會議&#xff0c;應有盡有。大多數 K-12 管理員對自己的 Wi-Fi 網絡的安全性充滿信心&#xff0c;并認為他們現有的網絡安全措施已經足夠。 不幸的是&#xff0c;這種信心往往是錯誤的。Wi-Fi 安全雖然經常…

【數據結構OJ題】鏈表中倒數第k個結點

原題鏈接&#xff1a;https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?tpId13&&tqId11167&rp2&ru/activity/oj&qru/ta/coding-interviews/question-ranking 目錄 1. 題目描述 2. 思路分析 3. 代碼實現 1. 題目描述 2. 思路分析 …

VectorStyler for Mac: 讓你的創意無限綻放的全新設計工具

VectorStyler for Mac是一款專為Mac用戶打造的矢量設計工具&#xff0c;它結合了功能強大的矢量編輯器和創意無限的樣式編輯器&#xff0c;讓你的創意無限綻放。 VectorStyler for Mac擁有直觀簡潔的用戶界面&#xff0c;讓你能夠輕松上手。它提供了豐富的矢量繪圖工具&#x…

JavaWeb博客項目--推薦算法--完整代碼及思路

基于用戶的協同過濾算法&#xff08;UserCF&#xff09; 因為我寫的是博客項目&#xff0c;博客數量可能比用戶數量還多 所以選擇基于用戶的協同過濾算法 重要思想 當要向用戶u進行推薦時&#xff0c;我們先找出與用戶u最相似的幾個用戶&#xff0c;再從這幾個用戶的喜歡的物…

數據可視化和數字孿生相互促進的關系

數據可視化和數字孿生是當今數字化時代中備受關注的兩大領域&#xff0c;它們在不同層面和領域為我們提供了深入洞察和智能決策的機會&#xff0c;隨著兩種技術的不斷融合發展&#xff0c;很多人會將他們聯系在一起&#xff0c;本文就帶大家淺談一下二者之間相愛相殺的關系。 …

Springboot集成ip2region離線IP地名映射-修訂版

title: Springboot集成ip2region離線IP地名映射 date: 2020-12-16 11:15:34 categories: springboot description: Springboot集成ip2region離線IP地名映射 1. 背景2. 集成 2.1. 步驟2.2. 樣例2.3. 響應實例DataBlock2.4. 響應實例RegionAddress 3. 打開瀏覽器4. 源碼地址&…

OpenShift 4 - 基于 MinIO 安裝 Red Hat Quay 鏡像倉庫

《OpenShift / RHEL / DevSecOps 匯總目錄》 說明&#xff1a;本文已經在 OpenShift 4.13 Quay 3.9 的環境中驗證 本文適合在單機 OpenShift 環境安裝 Red Hat Quay 鏡像倉庫。 另外《OpenShift 4 - 安裝 ODF 并部署紅帽 Quay (1 Worker)》也可以在單節點部署。 而《OpenShif…

前后端分離------后端創建筆記(11)用戶刪除

B站視頻&#xff1a;30-用戶刪除&結束語_嗶哩嗶哩_bilibili 1、現在我們要做一個刪除的功能 1.1 首先做一個刪除的功能接口&#xff0c;第一步先來到后端&#xff0c;做一個刪除的接口 2、刪除我們用Delete請求 3、方法名我給他改一下 3.1這里給他調一下刪除方法&#xf…

Java 中 List 集合排序方法

方式一&#xff1a; 調用List接口自己的sort方法排序 public static void main(String[] args) {List<Integer> numListnew ArrayList<>();numList.add(999);numList.add(123);numList.add(456);numList.add(66);numList.add(9);Collections.sort(numList); //使…

在一小時內構建您的深度學習應用程序

一、說明 我已經做了將近十年的數據分析。有時&#xff0c;我使用機器學習技術從數據中獲取見解&#xff0c;并且我習慣于使用經典 ML。 雖然我已經通過了神經網絡和深度學習的一些MOOC&#xff0c;但我從未在我的工作中使用過它們&#xff0c;這個領域對我來說似乎很有挑戰性。…