微信團隊分享:iOS版微信的高性能通用key-value組件技術實踐

本文來自微信開發團隊guoling的技術分享。php

一、前言

本文要分享的是iOS版微信內部正在推廣和使用的一個高性能通用key-value 組件的技術實踐過程,該組件在微信內部被命名爲MMKV(如下簡稱MMKV)。html

MMKV 是基於 mmap 內存映射的 key-value 組件,底層序列化/反序列化使用 protobuf 實現,性能高,穩定性強。但願對於有高性能key-value 組件或相似技術需求的IM同行,能經過本文得到必定的啓發。git

學習交流:程序員

- 即時通信開發交流羣:320837163[推薦]數據庫

- 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM安全

(本文同步發佈於:http://www.52im.net/thread-1461-1-1.html微信

二、MMKV 源起

在 iOS 微信的平常運營中,時不時就會爆發特殊文字引發 iOS 系統的 crash,《微信團隊分享:iOS版微信是如何防止特殊字符致使的炸羣、APP崩潰的?》一文裏面設計的技術方案是在關鍵代碼先後進行計數器的加減,經過檢查計數器的異常,來發現引發閃退的異常文字。網絡

微信團隊分享:iOS版微信是如何防止特殊字符致使的炸羣、APP崩潰的?》裏設計的技術方案大體原理就是:微信開發

1)在會話列表、會話界面等有大量 cell 的地方,但願新加的計時器不會影響滑動性能;架構

2)這些計數器還要永久存儲下來——由於閃退隨時可能發生。

這就須要一個性能很是高的通用 key-value 存儲組件,咱們考察了 NSUserDefaults、SQLite 等常見組件,發現都沒能知足如此苛刻的性能要求。考慮到這個防 crash 方案最主要的訴求仍是實時寫入,而 mmap 內存映射文件恰好知足這種需求,咱們嘗試經過它來實現一套 key-value 組件。

三、MMKV 原理

3.1 內存準備

經過 mmap 內存映射文件,提供一段可供隨時寫入的內存塊,App 只管往裏面寫數據,由 iOS 負責將內存回寫到文件,沒必要擔憂 crash 致使數據丟失。

3.2 數據組織

數據序列化方面咱們選用 protobuf 協議,pb 在性能和空間佔用上都有不錯的表現。考慮到咱們要提供的是通用 kv 組件,key 能夠限定是 string 字符串類型,value 則多種多樣(int/bool/double等)。要作到通用的話,考慮將 value 經過 protobuf 協議序列化成統一的內存塊(buffer),而後就能夠將這些 KV 對象序列化到內存中。

 

更多有關Protobuf的文章請見:

Protobuf通訊協議詳解:代碼演示、詳細原理介紹等

強列建議將Protobuf做爲你的即時通信應用數據傳輸格式

全方位評測:Protobuf性能到底有沒有比JSON快5倍?

一個基於Protocol Buffer的Java代碼演示

詳解如何在NodeJS中使用Google的Protobuf

3.3 寫入優化

標準 protobuf 不提供增量更新的能力,每次寫入都必須全量寫入。

考慮到主要使用場景是頻繁地進行寫入更新,咱們須要有增量更新的能力:

1)將增量 kv 對象序列化後,直接 append 到內存末尾;

2)這樣同一個 key 會有新舊若干份數據,最新的數據在最後;

3)那麼只需在程序啓動第一次打開 mmkv 時,不斷用後讀入的 value 替換以前的值,就能夠保證數據是最新有效的。

3.4 空間增加

使用 append 實現增量更新帶來了一個新的問題,就是不斷 append 的話,文件大小會增加得不可控。例如同一個 key 不斷更新的話,是可能耗盡幾百 M 甚至上 G 空間,而事實上整個 kv 文件就這一個 key,不到 1k 空間就存得下。這明顯是不可取的。

咱們須要在性能和空間上作個折中:

1)之內存 pagesize 爲單位申請空間,在空間用盡以前都是 append 模式;

2)當 append 到文件末尾時,進行文件重整、key 排重,嘗試序列化保存排重結果;

3)排重後空間仍是不夠用的話,將文件擴大一倍,直到空間足夠。

 

3.5 數據有效性

考慮到文件系統、操做系統都有必定的不穩定性,咱們另外增長了 crc 校驗,對無效數據進行甄別。在 iOS 微信現網環境上,咱們觀察到有平均約 70w 日次的數據校驗不經過。

四、MMKV 使用

4.1 快速上手

MMKV 提供一個全局的實例,能夠直接使用:

 

能夠看到,MMKV 在使用上仍是比較簡單的。若是不一樣業務須要區別存儲,也能夠單首創建本身的實例:

 

4.2 支持的數據類型

支持如下 C 語語言基礎類型:

bool、int3二、int6四、uint3二、uint6四、float、double

支持如下 ObjC 類型:

NSString、NSData、NSDate

五、MMKV 性能

寫了個簡單的測試,將 MMKV、NSUserDefaults 的性能進行對比(循環寫入1w 次數據,測試環境:iPhone X 256G, iOS 11.2.6,單位:ms)。

 

可見 MMKV 性能遠遠優於 iOS 自帶的 NSUserDefaults。另外,在測試中發現,NSUserDefaults 在每2-3次測試,就會有1次比較耗時的操做,懷疑是觸發了數據 synchronize 重整寫入。對比之下,MMKV即便觸發數據重整,也保持了性能的穩定高效。

目前 MMKV 已經在鵝廠內部開源(http://git.code.oa.com/wechat-team/mmkv),反饋比較好的話會考慮對外開源。

(原文連接:https://mp.weixin.qq.com/s/cZQ3FQxRJBx4px1woBaasg,本文略有改動)

附錄:有關微信、QQ的文章彙總

[1] QQ、微信團隊原創技術文章:

微信團隊分享:iOS版微信的高性能通用key-value組件技術實踐

微信團隊分享:iOS版微信是如何防止特殊字符致使的炸羣、APP崩潰的?

騰訊技術分享:Android手Q的線程死鎖監控系統技術實踐

微信團隊原創分享:iOS版微信的內存監控系統技術實踐

讓互聯網更快:新一代QUIC協議在騰訊的技術實踐分享

iOS後臺喚醒實戰:微信收款到帳語音提醒技術總結

騰訊技術分享:社交網絡圖片的帶寬壓縮技術演進之路

微信團隊分享:視頻圖像的超分辨率技術原理和應用場景

微信團隊分享:微信每日億次實時音視頻聊天背後的技術解密

QQ音樂團隊分享:Android中的圖片壓縮技術詳解(上篇)

QQ音樂團隊分享:Android中的圖片壓縮技術詳解(下篇)

騰訊團隊分享:手機QQ中的人臉識別酷炫動畫效果實現詳解

騰訊團隊分享 :一次手Q聊天界面中圖片顯示bug的追蹤過程分享

微信團隊分享:微信Android版小視頻編碼填過的那些坑》 

微信手機端的本地數據全文檢索優化之路》 

企業微信客戶端中組織架構數據的同步更新方案優化實戰

微信團隊披露:微信界面卡死超級bug「15。。。。」的前因後果

QQ 18年:解密8億月活的QQ後臺服務接口隔離技術

月活8.89億的超級IM微信是如何進行Android端兼容測試的

以手機QQ爲例探討移動端IM中的「輕應用」

一篇文章get微信開源移動端數據庫組件WCDB的一切!

微信客戶端團隊負責人技術訪談:如何着手客戶端性能監控和優化

微信後臺基於時間序的海量數據冷熱分級架構設計實踐

微信團隊原創分享:Android版微信的臃腫之困與模塊化實踐之路

微信後臺團隊:微信後臺異步消息隊列的優化升級實踐分享

微信團隊原創分享:微信客戶端SQLite數據庫損壞修復實踐》 

騰訊原創分享(一):如何大幅提高移動網絡下手機QQ的圖片傳輸速度和成功率》 

騰訊原創分享(二):如何大幅壓縮移動網絡下APP的流量消耗(下篇)》 

騰訊原創分享(二):如何大幅壓縮移動網絡下APP的流量消耗(上篇)》 

微信Mars:微信內部正在使用的網絡層封裝庫,即將開源》 

如約而至:微信自用的移動端IM網絡層跨平臺組件庫Mars已正式開源》 

開源libco庫:單機千萬鏈接、支撐微信8億用戶的後臺框架基石 [源碼下載]》 

微信新一代通訊安全解決方案:基於TLS1.3的MMTLS詳解》 

微信團隊原創分享:Android版微信後臺保活實戰分享(進程保活篇)》 

微信團隊原創分享:Android版微信後臺保活實戰分享(網絡保活篇)》 

Android版微信從300KB到30MB的技術演進(PPT講稿) [附件下載]》 

微信團隊原創分享:Android版微信從300KB到30MB的技術演進》 

微信技術總監談架構:微信之道——大道至簡(演講全文)

微信技術總監談架構:微信之道——大道至簡(PPT講稿) [附件下載]》 

如何解讀《微信技術總監談架構:微信之道——大道至簡》

微信海量用戶背後的後臺系統存儲架構(視頻+PPT) [附件下載]

微信異步化改造實踐:8億月活、單機千萬鏈接背後的後臺解決方案》 

微信朋友圈海量技術之道PPT [附件下載]》 

微信對網絡影響的技術試驗及分析(論文全文)》 

一份微信後臺技術架構的總結性筆記》 

架構之道:3個程序員成就微信朋友圈日均10億發佈量[有視頻]》 

快速裂變:見證微信強大後臺架構從0到1的演進歷程(一)

快速裂變:見證微信強大後臺架構從0到1的演進歷程(二)》 

微信團隊原創分享:Android內存泄漏監控和優化技巧總結》 

全面總結iOS版微信升級iOS9遇到的各類「坑」》 

微信團隊原創資源混淆工具:讓你的APK立減1M》 

微信團隊原創Android資源混淆工具:AndResGuard [有源碼]》 

Android版微信安裝包「減肥」實戰記錄》 

iOS版微信安裝包「減肥」實戰記錄》 

移動端IM實踐:iOS版微信界面卡頓監測方案》 

微信「紅包照片」背後的技術難題》 

移動端IM實踐:iOS版微信小視頻功能技術方案實錄》 

移動端IM實踐:Android版微信如何大幅提高交互性能(一)

移動端IM實踐:Android版微信如何大幅提高交互性能(二)

移動端IM實踐:實現Android版微信的智能心跳機制》 

移動端IM實踐:WhatsApp、Line、微信的心跳策略分析》 

移動端IM實踐:谷歌消息推送服務(GCM)研究(來自微信)

移動端IM實踐:iOS版微信的多設備字體適配方案探討》 

信鴿團隊原創:一塊兒走過 iOS10 上消息推送(APNS)的坑

騰訊信鴿技術分享:百億級實時消息推送的實戰經驗

>> 更多同類文章 ……

[2] 有關QQ、微信的技術故事:

QQ和微信兇猛成長的背後:騰訊網絡基礎架構的這些年

閒話即時通信:騰訊的成長史本質就是一部QQ成長史

2017微信數據報告:日活躍用戶達9億、日發消息380億條

騰訊開發微信花了多少錢?技術難度真這麼大?難在哪?

技術往事:創業初期的騰訊——16年前的冬天,誰動了馬化騰的代碼》 

技術往事:史上最全QQ圖標變遷過程,追尋IM巨人的演進歷史》 

技術往事:「QQ羣」和「微信紅包」是怎麼來的?》 

開發往事:深度講述2010到2015,微信一路風雨的背後》 

開發往事:微信千年不變的那張閃屏圖片的由來》 

開發往事:記錄微信3.0版背後的故事(距微信1.0發佈9個月時)》 

一個微信實習生自述:我眼中的微信開發團隊

首次揭祕:QQ實時視頻聊天背後的神祕組織

>> 更多同類文章 ……

(本文同步發佈於:http://www.52im.net/thread-1461-1-1.html

相關文章
相關標籤/搜索