NoSQL之一:Memcached

来源:https://www.cnblogs.com/supersnowyao/archive/2020/05/15/12897368.html
-Advertisement-
Play Games

一、NoSQL簡介 NoSQL並不是No SQL(不再需要SQL),而是指Not Only SQL(不僅僅只有SQL)。NoSQL並不是用來替代關係型資料庫的,而是在某些使用關係型資料庫不合適的場景中,可以使用NoSQL資料庫進行優化,而在系統中主要的、常規的數據仍然使用關係型資料庫。 常用的NoS ...


一、NoSQL簡介

       NoSQL並不是No SQL(不再需要SQL),而是指Not Only SQL(不僅僅只有SQL)。NoSQL並不是用來替代關係型資料庫的,而是在某些使用關係型資料庫不合適的場景中,可以使用NoSQL資料庫進行優化,而在系統中主要的、常規的數據仍然使用關係型資料庫。
  常用的NoSQL資料庫有Memcached、Redis、MongoDB等,其中前兩者屬於鍵值對資料庫,後者屬於文檔資料庫。它們都有各自的優缺點以及使用場景。

二、Memcached介紹與安裝

       Memcached是一個專門用來做緩存的資料庫,緩存的數據都是在記憶體當中,當資料庫重啟之後,數據也就都丟失了。其相當於一個Dictionary鍵值對集合,根據Key值取Value值。

  1、Memcached安裝

         從網上下載Memcached-win64-1.4.4-14.zip安裝包。解壓後,通過管理員許可權執行如下命令,可將其安裝成服務:

G:\MemcachedAfterInstall>memcached.exe -d install

   2、Memcached可視化工具

    TreeNMS是一款Redis、Memcached可視化客戶端工具,實現基於Web方式對Redis、Memcached資料庫進行管理、維護。可通過如下鏈接http://www.treesoft.cn/dms.html進行下載。

    下圖即該工具的使用界面:



 三、在.Net Core中的使用

  1、組件包的安裝與使用

    在.Net Core項目中調用Memcached資料庫的資源,可以使用EnyimMemcachedCore客戶端組件包。

    通過該組件向Memcached資料庫存入數據有三種模式,分別如下:

      1)Set:存在則覆蓋,不存在則新增;

      2)Replace:如果存在則覆蓋,並且返回true;如果不存在則不處理,並且返回false;

      3)Add:如果不存在則新增,並且返回true;如果存在則不處理,並且返回false;

    故,根據以上可知,如果沒有特殊要求一般用Set即可。

    註意:Memcached資料庫中的key的長度最高為250個字元,value的值最大為1M。

  2、案例演示

    為了演示方便,創建了一個基於.Net Core3.1版本的WPF項目,界面如下:

 

 

 

 

 

 

 

 

 

     1)存儲數據、讀取數據 

public partial class MainWindow : Window
{
  private readonly MemcachedClient _memcachedClient;
  private static readonly ILoggerFactory _loggerFactory = new LoggerFactory();
  public MainWindow()
  {
    InitializeComponent();
    var options = new MemcachedClientOptions();
    options.AddServer("127.0.0.1", 11211);
    _memcachedClient = new MemcachedClient(_loggerFactory, new MemcachedClientConfiguration(_loggerFactory, options));
  }
}
private void btnStorage_Click(object sender, RoutedEventArgs e)
{
  var result = _memcachedClient.Store(StoreMode.Set, "supersnow", "yao");
  MessageBox.Show($"保存成功?{result}");
}

private void btnRead_Click(object sender, RoutedEventArgs e)
{
  var result = _memcachedClient.Get("supersnow");
  MessageBox.Show($"讀取結果:{result}");
}  

  

     2)存儲類數據、讀取類數據

private async void btnStorage_Class_Click(object sender, RoutedEventArgs e)
{
  var person = new Person
  {
    Name = "SuperSnow",
    Age = 25
  };
  var result = await _memcachedClient.StoreAsync(StoreMode.Set, "person_key", person, TimeSpan.FromSeconds(3600));
  MessageBox.Show($"保存Person成功?{result}");
}
private async void btnRead_Class_Click(object sender, RoutedEventArgs e) {   var result = await _memcachedClient.GetAsync<Person>("person_key");   if (result.Value == null)     MessageBox.Show("數據已經失效");   else     MessageBox.Show($"讀取Person結果:{result.Value.Name}:{result.Value.Age}"); } public class Person {   public string Name { get; set; }   public int Age { get; set; } }
  

  

     3)讀取數據異常

    對於讀取數據失敗時,返回結果為false。但是,此時並不知道失敗的原因是什麼,可以通過如下方法獲取失敗原因:

 private void btnRead_Exception_Click(object sender, RoutedEventArgs e)
 {
    var result = _memcachedClient.ExecuteRemove("abc");
    MessageBox.Show($"結果:{result.Success},Message:{result.Message},Exception:{result.Exception},StatusCode:{result.StatusCode},InnerResult:{result.InnerResult.Message}");
 } 

  

     4)Memcached Cas操作

    Cas操作類似於關係型資料庫中的“樂觀鎖”,查詢的時候會順帶查出一個Cas值,在寫入的時候會帶著這個Cas值,如果發現Cas值改變了,則說明已經有其他操作提前修改了相應的值。本質上來說Cas就是用來解決併發問題,通過讀取一個值,然後做一些處理或判斷,然後再寫回到資料庫中,這種操作有可能產生併發問題。

private CasResult<Person> casResult;
 private void btnA_Read_Click(object sender, RoutedEventArgs e)
 {
     casResult = _memcachedClient.GetWithCas<Person>("person_key");
     if (casResult.Result != null)
         MessageBox.Show($"讀取Person結果:{casResult.Result.Name}:{casResult.Result.Age}");
     else
         MessageBox.Show("沒有結果");
 }

 private void btnB_Save_Click(object sender, RoutedEventArgs e)
 {
     var result = _memcachedClient.GetWithCas<Person>("person_key");
     if (result.Result.Age >= 25)
         result.Result.Age++;
     var tag = _memcachedClient.Cas(StoreMode.Set, "person_key", result.Result, result.Cas);
     if (tag.Result)
         MessageBox.Show("修改成功");
     else
         MessageBox.Show("修改失敗");
 }

 private void btnA_Save_Click(object sender, RoutedEventArgs e)
 {
     if (casResult.Result.Age >= 25)
         casResult.Result.Age++;
     else
         casResult.Result.Age++;
     var tag = _memcachedClient.Cas(StoreMode.Set, "person_key", casResult.Result, casResult.Cas);
     if (tag.Result)
         MessageBox.Show("修改成功");
     else
         MessageBox.Show("修改失敗");
 }

 

     5)Memcached集群

    Memcached重啟之後,在短時間內大量的請求會涌入資料庫,給資料庫造成巨大壓力,解決此類問題的方法就是使用集群,即使用多Memcached伺服器提供服務。

    除此之外,Memcached還有可能面臨“雪崩”問題,如果所有緩存設置過期時間是一樣的,或者失效時間在一個短距離的範圍內。那麼每隔一段時間就會造成一次資料庫訪問的高峰。此類問題的解決方法就是將不同緩存的緩存失效時間設置成不一樣,如對失效時間加上隨機數。

    Memcached集群的節點之間不用進行通訊和數據同步,只需要在多個伺服器上啟動多個Memcached資料庫即可。客戶端決定了將數據寫入不同的Memcached實例,不用做主從複製操作。

    節點定位演算法有很多種,最常用的就是Ketama演算法,該演算法根據Key算出一個hash值,然後根據hash值再得出伺服器。如下例所示:

private readonly MemcachedClient _memcachedClient;
private static readonly ILoggerFactory _loggerFactory = new LoggerFactory();
public MainWindow()
{
    InitializeComponent();

    var options = new MemcachedClientOptions();
    options.AddServer("127.0.0.1", 11211);
    options.AddServer("127.0.0.1", 11212);
    options.NodeLocatorFactory = new DefaultNodeLocatorFactory(11211);
    _memcachedClient = new MemcachedClient(_loggerFactory, new MemcachedClientConfiguration(_loggerFactory, options));
}
private void btnA_Save_Cluster_Click(object sender, RoutedEventArgs e)
{
    var person = new Person
    {
        Name = "張三",
        Age = 25
    };
    var result =  _memcachedClient.Store(StoreMode.Set, "1", person);
    MessageBox.Show($"保存Person成功?{result}");
}

private void btnA_Read_Cluster_Click(object sender, RoutedEventArgs e)
{
    var result = _memcachedClient.Get<Person>("1");
    if (result == null)
        MessageBox.Show("數據已經失效");
    else
        MessageBox.Show($"讀取Person結果:{result.Name}:{result.Age}");
}

private void btnB_Save_Cluster_Click(object sender, RoutedEventArgs e)
{
    var person = new Person
    {
        Name = "李四",
        Age = 23
    };
    var result = _memcachedClient.Store(StoreMode.Set, "2", person);
    MessageBox.Show($"保存Person成功?{result}");
}

private void btnB_Read_Cluster_Click(object sender, RoutedEventArgs e)
{
    var result = _memcachedClient.Get<Person>("2");
    if (result == null)
        MessageBox.Show("數據已經失效");
    else
        MessageBox.Show($"讀取Person結果:{result.Name}:{result.Age}");
} 

 

     通過如下命令分別啟動兩個Memcached實例:

G:\MemcachedAfterInstall>memcached.exe -p 11212
G:\MemcachedAfterInstall>memcached.exe -p 11211

    在TreeNMS系統中配置兩個資料庫連接:

    由於Key=1和Key=2的hash值不同,所以緩存數據分別存在於兩個Memcached實例中,如下圖所示:

 

 

 


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

-Advertisement-
Play Games
更多相關文章
  • 用戶和組的相關概念 賬號:是一種用來記錄單個用戶或是多個用戶的數據。在Linux 上的賬號可以分成兩類: 用戶賬號 用來儲存單一用戶的數據,你可以使用一個用戶賬號,來儲存某一個用戶的數據。 群組賬號 用來儲存多個用戶的信息,每一個群組賬號可以用來記錄一組用戶的數據。 依照賬號的位置 本機賬號: 儲存 ...
  • 目錄操作 基礎目錄操作 linux 沒有類似windows一樣的盤符之分,所有的目錄都是以“根‘ / ’”開始,linux 是多用戶登陸, 在 /home/ 的目錄下,存放著已添加用戶的用戶目錄。每個用戶一個文件夾,文件夾名為用戶名 // 下文中 $ 表示終端的提示符,不包含在命令當中 $ pwd ...
  • NoSQL 開發中或多或少都會用到,也是面試必問知識點。最近這幾天的面試每一場都問到了。但是感覺回答的並不好,還有很多需要梳理的知識點。這裡通過幾篇 Redis 筆記整個梳理一遍,後面再加上面試題。 Redis 系列: 1. Redis系列(一)Redis入門 2. Redis系列(二)Redi... ...
  • NoSQL 開發中或多或少都會用到,也是面試必問知識點。最近這幾天的面試每一場都問到了。但是感覺回答的並不好,還有很多需要梳理的知識點。這裡通過幾篇 Redis 筆記整個梳理一遍,後面再加上面試題。 Redis 系列: 1. Redis系列(一)Redis入門 2. Redis系列(二)Redi... ...
  • NoSQL 開發中或多或少都會用到,也是面試必問知識點。最近這幾天的面試每一場都問到了。但是感覺回答的並不好,還有很多需要梳理的知識點。這裡通過幾篇 Redis 筆記整個梳理一遍,後面再加上面試題。 Redis 系列: 1. Redis系列(一)Redis入門 2. Redis系列(二)Redi... ...
  • NoSQL 開發中或多或少都會用到,也是面試必問知識點。最近這幾天的面試每一場都問到了。但是感覺回答的並不好,還有很多需要梳理的知識點。這裡通過幾篇 Redis 筆記整個梳理一遍,後面再加上面試題。 Redis 系列: 1. Redis系列(一)Redis入門 2. Redis系列(二)Redi... ...
  • NoSQL 開發中或多或少都會用到,也是面試必問知識點。最近這幾天的面試每一場都問到了。但是感覺回答的並不好,還有很多需要梳理的知識點。這裡通過幾篇 Redis 筆記整個梳理一遍,後面再加上面試題。 Redis 系列: 1. Redis系列(一)Redis入門 2. Redis系列(二)Redi... ...
  • NoSQL 開發中或多或少都會用到,也是面試必問知識點。最近這幾天的面試每一場都問到了。但是感覺回答的並不好,還有很多需要梳理的知識點。這裡通過幾篇 Redis 筆記整個梳理一遍,後面再加上面試題。 Redis 系列: 1. Redis系列(一)Redis入門 2. Redis系列(二)Redi... ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...