微軟併發Key-Value存儲庫FASTER介紹

来源:https://www.cnblogs.com/knoww/archive/2019/11/02/11781405.html
-Advertisement-
Play Games

微軟支持併發的Key-Value 存儲庫有C++與C#兩個版本。號稱迄今為止最快的併發鍵值存儲。下麵是C#版本翻譯: FASTER C#可在.NET Framework和.NET Core中運行,並且可以在單線程和併發設置中使用。經過測試,可以在Windows和Linux上使用。它公開了一種API, ...


  微軟支持併發的Key-Value 存儲庫有C++與C#兩個版本。號稱迄今為止最快的併發鍵值存儲。下麵是C#版本翻譯:

FASTER C#可在.NET Framework和.NET Core中運行,並且可以在單線程和併發設置中使用。經過測試,可以在Windows和Linux上使用。它公開了一種API,該API可以執行讀取,盲更新(Upserts)和讀取-修改-寫入(RMW)操作的混合。它支持大於記憶體的數據,並接受IDevice將日誌存儲在文件中的實現。提供了IDevice本地文件系統的實現,可以寫入遠程文件系統。或者將遠程存儲映射到本地文件系統中。FASTER可以用作傳統併發數據結構類似ConcurrentDictionary的高性能替代品,並且還支持大於記憶體的數據。它支持增量非增量數據結構類型的檢查點。

FASTER支持三種基本操作:

  1. Read:從鍵值存儲中讀取數據
  2. Upsert:將值盲目向上插入到存儲中(不檢查先前的值)
  3. Read-Modify-Write:更新存儲區中的值,用於實現“求和”和“計數”之類的操作。

構建

在實例化FASTER之前,您需要創建FASTER將使用的存儲設備。如果使用的是可移植類型byteintdouble類型,則僅需要混合日誌設備。如果使用對象,則需要創建一個單獨的對象日誌設備。

IDevice log = Devices.CreateLogDevice("C:\\Temp\\hybridlog_native.log");

然後,按如下方式創建一個FASTER實例:

fht = new FasterKV<Key, Value, Input, Output, Empty, Functions>

  (1L << 20, new Functions(), new LogSettings { LogDevice = log });

構造函數的類型參數

有六個基本概念,在實例化FASTER時作為通用類型參數提供:

  1. Key:這是的類型,例如long
  2. Value:這是存儲在FASTER中的值的類型。
  3. Input:這是調用Read或RMW時提供給FASTER的輸入類型。它可以被視為讀取或RMW操作的參數。例如,對於RMW,可是增量累加到值。
  4. Output:這是讀操作的輸出類型將值的相關部分複製到輸出。
  5. Context:操作的用戶定義上下文如果沒有必要使用Empty
  6. Functions需要回調時,使用IFunctions<>調用。

回調函數

用戶提供一個實例IFunctions<>。此類型封裝了所有回調,下麵將對其進行介紹:

  1. SingleReader和併發讀ConcurrentReader:這些用於讀取存儲值並將它們複製到Output。單個讀取器可以假定沒有併發操作。
  2. SingleWriter和ConcurrentWriter:這些用於將值從源值寫入存儲。
  3. Completion callbacks完成回調:各種操作完成時調用。
  4. RMWUpdaters:用戶指定了三個更新器,InitialUpdater,InPlaceUpdater和CopyUpdater。它們一起用於實現RMW操作。
  5. Hash Table Siz哈希表大小:這是分配給FASTER的存儲行數,其中每個64位元組。
  6. LogSettings 日誌設置:這些設置與日誌的大小設備。
  7. Checkpoint設置:這些是與檢查相關的設置,例如檢查類型和文件夾。
  8. Serialization序列化設置:用於為鍵和值類型提供自定義序列化程式。序列化程式實現IObjectSerializer<Key>鍵和IObjectSerializer<Value>值。只有C#類對象非可移植類型才需要這些。
  9. Key比較器:用於為key提供更好的比較器IFasterEqualityComparer<Key>

構造函數參數

FASTER的總記憶體占用量由以下參數控制:

  1. 哈希表大小:此參數(第一個構造函數參數)乘以64是記憶體中哈希表的大小(以位元組為單位)。
  2. 日誌大小:logSettings.MemorySizeBits表示混合日誌的記憶體部分的大小(以位為單位)。換句話說對於參數設置B,日誌的大小為2 ^ B位元組。如果日誌指向類對象,則此大小不包括對象的大小,因為FASTER無法訪問此信息。日誌的較舊部分溢出到存儲中。

Sessions (Threads)會話(線程)

實例化FASTER之後,線程可以使用Session使用FASTER

fht.StartSession();

fht.StopSession();

當所有線程都在FASTER上完成操作後,您最終銷毀FASTER實例:

fht.Dispose();

示例

以下是一個簡單示例,其中所有數據都在記憶體中,因此我們不必擔心掛起的I / O操作。在此示例中也沒有檢查點。

public static void Test()

{

  var log = Devices.CreateLogDevice("C:\\Temp\\hlog.log");

  var fht = new FasterKV<long, long, long, long, Empty, Funcs>

    (1L << 20, new Funcs(), new LogSettings { LogDevice = log });

  fht.StartSession();

  long key = 1, value = 1, input = 10, output = 0;

  fht.Upsert(ref key, ref value, Empty.Default, 0);

  fht.Read(ref key, ref input, ref output, Empty.Default, 0);

  Debug.Assert(output == value);

  fht.RMW(ref key, ref input, Empty.Default, 0);

  fht.RMW(ref key, ref input, Empty.Default, 0);

  fht.Read(ref key, ref input, ref output, Empty.Default, 0);

  Debug.Assert(output == value + 20);

  fht.StopSession();

  fht.Dispose();

  log.Close();

}

此示例的函數

public class Funcs : IFunctions<long, long, long, long, Empty>

{

  public void SingleReader(ref long key, ref long input, ref long value, ref long dst) => dst = value;

  public void SingleWriter(ref long key, ref long src, ref long dst) => dst = src;

  public void ConcurrentReader(ref long key, ref long input, ref long value, ref long dst) => dst = value;

  public void ConcurrentWriter(ref long key, ref long src, ref long dst) => dst = src;

  public void InitialUpdater(ref long key, ref long input, ref long value) => value = input;

  public void CopyUpdater(ref long key, ref long input, ref long oldv, ref long newv) => newv = oldv + input;

  public void InPlaceUpdater(ref long key, ref long input, ref long value) => value += input;

  public void UpsertCompletionCallback(ref long key, ref long value, Empty ctx) { }

  public void ReadCompletionCallback(ref long key, ref long input, ref long output, Empty ctx, Status s) { }

  public void RMWCompletionCallback(ref long key, ref long input, Empty ctx, Status s) { }

  public void CheckpointCompletionCallback(Guid sessionId, long serialNum) { }

}

更多例子

檢查點和恢復

FASTER支持基於檢查點的恢復。每個新的檢查點都會保留(或使之持久)其他用戶操作(讀取,更新或RMW)。FASTER允許客戶端線程跟蹤已持久的操作和未使用基於會話的API的操作。

回想一下,每個FASTER線程都會啟動一個與唯一的Guid相關聯的會話。所有FASTER線程操作(讀取,Upsert,RMW)都帶有單調序列號。在任何時間點,都可以調用Checkpoint以啟動FASTER的非同步檢查點。在調用之後Checkpoint,(最終)向每個FASTER線程通知一個序列號,這樣可以確保直到該序列號之前的所有操作以及在該序列號之後沒有任何操作被保留為該檢查點的一部分。FASTER線程可以使用此序列號來清除等待執行的操作的任何記憶體緩衝區。

在恢復期間,線程可以使用繼續使用相同的Guid進行會話ContinueSession。該函數返回線程本地序列號,直到恢復該會話哈希為止。從那時起,新線程可以使用此信息來重播所有未提交的操作。

下麵一個單線程的簡單恢復示例。

public class PersistenceExample

{

  private FasterKV<long, long, long, long, Empty, Funcs> fht;

  private IDevice log;

  

  public PersistenceExample()

  {

    log = Devices.CreateLogDevice("C:\\Temp\\hlog.log");

    fht = new FasterKV<long, long, long, long, Empty, Funcs>

    (1L << 20, new Funcs(), new LogSettings { LogDevice = log });

  }

  

  public void Run()

  {

    IssuePeriodicCheckpoints();

    RunSession();

  }

  

  public void Continue()

  {

    fht.Recover();

    IssuePeriodicCheckpoints();

    ContinueSession();

  }

  

  /* Helper Functions */

  private void RunSession()

  {

    Guid guid = fht.StartSession();

    System.IO.File.WriteAllText(@"C:\\Temp\\session1.txt", guid.ToString());

    

    long seq = 0; // sequence identifier

    

    long key = 1, input = 10;

    while(true)

    {

      key = (seq % 1L << 20);

      fht.RMW(ref key, ref input, Empty.Default, seq);

      seq++;

    }

    // fht.StopSession() - outside infinite loop

  }

  

  private void ContinueSession()

  {

    string guidText = System.IO.File.ReadAllText(@"C:\\Temp\session1.txt");

    Guid sessionGuid = Guid.Parse(guidText);

    

    long seq = fht.ContinueSession(sessionGuid); // recovered seq identifier

    seq++;

    

    long key = 1, input = 10;

    while(true)

    {

      key = (seq % 1L << 20);

      fht.RMW(ref key, ref input, Empty.Default, seq);

      seq++;

    }

  }

  

  private void IssuePeriodicCheckpoints()

  {

    var t = new Thread(() =>

    {

      while(true)

      {

        Thread.Sleep(10000);

fht.StartSession();

        fht.TakeCheckpoint(out Guid token);

        fht.CompleteCheckpoint(token, true);

fht.StopSession();

      }

    });

    t.Start();

  }

}

FASTER支持兩種檢查點概念:“快照”和“摺疊”。前者是將記憶體中的完整快照複製到一個單獨的快照文件中,而後者是自上一個檢查點以來更改的增量檢查點。摺疊有效地將混合日誌的只讀標記移到尾部,因此所有數據都作為同一混合日誌的一部分保留(沒有單獨的快照文件)。所有後續更新均寫入新的混合日誌尾部位置,這使Fold-Over具有增量性質。

項目路徑:

https://github.com/Microsoft/FASTER/tree/master/cs

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文介紹下在windows系統下安裝python和python環境搭建。 安裝PYTHON 首先,我們去python的官方網站下載python安裝包。官網地址:https://www.python.org/downloads/跳轉到官網後,我們點擊下載按鈕,如圖: 在網頁下方還可下載python的歷 ...
  • python初學者,想要做一個簡單但是實用的小程式,實現目標如下: 可以手動選擇本地excel文件,然後點擊確認後,生成一個“將不同行業放在不同sheet”的新工作簿。 從而免去每個月都需要在各個excel表格中反覆匹配行業、反覆篩選、反覆複製粘貼到不同工作表的過程 實現我“做一個輕鬆快樂、無憂無慮 ...
  • [TOC] 1. 前言 本文以go1.12.5版本分析,map相關的源碼在runtime包的map開頭的幾個文件中,主要為map.go。 go的map底層實現方式是hash表(C++的map是紅黑樹實現,而C++ 11新增的unordered_map則與go的map類似,都是hash實現)。go m ...
  • 文件操作的相關類所在的命名空間在System.IO中File 操作文件,對文件整體操作,拷貝,刪除,剪切等等Directory 操作目錄(文件夾)靜態類Path 對文件或目錄的路徑進行操作(操作的是字元串本身)Stream 文件流 1.FileStream 文件流 MemoryStream 記憶體流 ...
  • 一、簡介 枚舉是一組命名整型常量;枚舉類型是使用 enum 關鍵字聲明的;C# 枚舉是值類型。 二、語法 枚舉的語法: public:訪問修飾符,公共的公開的,哪都可以訪問; enum:關鍵字,聲明枚舉的關鍵字; 枚舉名:要符合Pascal命名規範; 將枚舉聲明到命名空間下麵,類的外面,表示這個命名 ...
  • 一、簡介 1.常量可以當做常規的變數,只是他們的值在定義後不能在被修改。 2.常量是固定值,程式執行期間不會改變。常量可以是任何的基本數據類型,比如整數常量,浮點常量,字元串常量或者字元串常量,還有枚舉常量。 二、常量說明 例如: 整數常量:24小時,365天 小數/浮點常量:圓周率3.14 字元: ...
  • 【ASP.NET Core學習】Razor頁面創建,添加模型,模型驗證,篩選器 ...
  • 閑來無事,整理一下最近參加面試遇到的一些優點意思的面試題。 1. finally與return相關的問題 大家直接看代碼吧 try語句塊內執行return語句後,finally里的語句還會執行嘛?答案是肯定的。 原理可以參考這篇博文,傳送門。 結論是finally中的代碼始終都會執行。 2. 4G的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...