Redis Stack功能介紹及redis-om-dotnet使用示例

yswenli發表於2024-04-11

為了簡化開發人員對較新的 Redis 模組及其提供的功能的體驗,同時簡化支援其功能的文件和客戶端。以幫助開發人員從開始使用 Redis 的那一刻起,就能充分提高工作效率。Redis Stack誕生了。Redis Stack 將較新的 Redis 模組整合到一個產品中。這使得我們可以輕鬆地開始使用我們基於 Redis 的搜尋、文件、圖形和時間序列功能進行構建。

Redis Stack 是由三個元件組成的套件:

1. Redis Stack Server 將開源 Redis 與 RediSearch、RedisJSON、RedisGraph、RedisTimeSeries 和 RedisBloom 結合在一起。

2. RedisInsight 一款強大的工具,用於視覺化和最佳化 Redis 資料,它使實時應用開發比以往任何時候都更簡單、更有趣。

3. Redis Stack Client SDK 包括領先的 Java、JavaScript 和 Python 官方 Redis客戶端。 這些客戶端還包括Redis全新的物件對映庫套件,這些庫提供了對開發人員友好的抽象,只需幾行程式碼即可大大提高工作效率。這些庫被稱為 Redis OM for .NET、Node.js、Java、Python,它們還能比以往更輕鬆地與 Spring、ASP.NET Core、FastAPI 和 Express 等主要應用程式框架整合。

Redis Stack 入門

幾種快速入門 Redis Stack 的方法:

·直接從 redis.io 下載 Redis Stack

· 透過你最喜歡的軟體包管理器安裝,或直接啟動 Redis Stack docker 映象進行安裝

· 透過在 Redis Enterprise Cloud 上建立免費資料庫或在雲中部署 Redis Stack。Redis Enterprise 中提供了 Redis Stack 的能力,供使用者自行管理或在企業內部部署。

當你的 Redis Stack Server 成功啟動並執行,你就可以立即利用 RedisInsight 來視覺化、分析並最佳化你的 Redis 資料。RedisInsight 包含一系列指南,可指導你瞭解多個 Redis Stack 使用案例。Redis Stack 現已全面支援 Redis 6.2,並已存在支援 Redis 7.0 的候選版本。

客戶端側:在幾款領先的Redis客戶端提供了Redis的全新物件對映庫redis-om-dotnet

Redis Stack會替代Redis嗎?

Redis Stack 將為實時應用領域帶來無限可能,但Redis Stack 並不是 Redis 的替代品。Redis 是一項核心開源技術,企業始終可以選擇下載、構建、安裝和執行開源 Redis。當你準備好執行 Redis Stack 時,你可以使用Redis複製機制或透過載入你的RDB或AOF檔案來輕鬆遷移資料。

Redis Stack的許可模式

· Redis Stack 的所有程式碼庫元件都是開放的,每個人都可以免費使用

· Redis Stack Server 是根據 Redis Source Available License 2.0(RSALv2)(與Redis 模組使用的許可證相同)提供的。

· 根據現有的伺服器端公共許可證(SSPL)提供 RedisInsight。

· Redis clients 和Redis的物件對映庫已根據開源 MIT 許可釋出。

FAQ

Redis Stack 包含哪些元件?

· Redis Stack 是一個單獨的軟體包,其中包括搭載了最新的 Redis 模組的開源 Redis(即 Redis Stack Server)和 RedisInsight。

· Redis Stack Server 的初始版本中,包含了五個模組: RedisJSON、RedisSearch、RedisGraph、RedisTimeSeries 和 RedisBloom。

· Redis Stack 由官方 Redis client 和物件對映庫提供支援,允許開發人員在多個應用框架(包括 Spring、ASP.Net Core、Express 和 FastAPI)中輕鬆使用高階的 Redis Stack 功能。

Redis Stack 為開發人員提供了哪些功能?

· 索引和查詢 Redis 資料、聚合、執行全文搜尋

· 執行高階向量相似性搜尋(KNN)

· 高效儲存和處理巢狀的 JSON 文件

· 以屬性圖的形式構建和模擬關係

· 儲存、查詢和聚合時間序列資料

· 充分利用快速、空間和計算效率高的機率資料結構

· 使用 RedisInsight 輕鬆實現 Redis 資料的視覺化、除錯和分析

Redis Stack 還會新增更多功能嗎?

如果有以下情況,Redis官方團隊會考慮為 Redis Stack 新增新功能甚至模組:

1. 存在社群的需求

2. 新功能符合Redis的願景

3. Redis公司的工程團隊能夠正式支援新增功能

為什麼 RedisGears 不是 Redis Stack 第一個版本的一部分?

· RedisGears 為 Redis 增加了資料庫觸發器、流處理、分散式函式和完全可程式設計性。為 JavaScript 提供 GA 支援後,將 RedisGears 新增到 Redis Stack 中。

什麼是 Redis 物件對映庫(object-mapping libraries)?

· Redis 物件對映庫在 Redis 命令應用程式介面之上提供了一個抽象層次,就像 ORM 對 SQL 資料庫的作用一樣。從而可以把 Redis 客戶端核心庫與 Redis 物件對映庫區分開來。

核心 Redis 客戶端庫有以下職責:

· 執行 Redis 協議(RESP 等)

· 管理連線(TCP 等)、重新連線、伺服器發現等

· 管理執行邏輯(執行緒、非同步 io 等)

· 為執行任意 Redis 命令暴露 Redis 的 API

· 以常用的互動語法風格的方式暴露 Redis 命令

· 透過連線字串連線到任何 Redis 已部署的例項

物件對映庫提供了額外的能力:

· 允許開發人員用盡可能少的程式碼行實現常見的 Redis 用例。目前,這包括領域建模和流暢的查詢 API。未來,其他常見 Redis 用例也將受到支援,包括快取、會話儲存、速率限制、排行榜和去重器。

· 為 Redis Stack 提供的功能提供高階應用程式介面

· 在不暴露底層 Redis 命令的情況下提供 Redis 的優勢能力

· 與主要應用框架(如ASP.NET Core、TJC.Cyclops、Spring、FastAPI、Express)整合

這些物件對映庫總是依賴於一個或多個 Redis 核心庫。

適用於 .NET 的 RedisOM

Redis OM .NET 是一個專門構建的庫,用於處理 Redis Stack 中的文件。在本教程中,我們將構建一個簡單的 ASP.NET Core Web-API 應用,用於在簡單的人員和地址模型上執行 CRUD 操作,我們將使用 Redis OM .NET 完成所有這些操作。

先決條件

  • .NET 6 SDK
  • 用於編寫 .NET 的任何 IDE(Visual Studio、Rider、Visual Studio Code)。
  • RediSearch 必須作為 Redis 堆疊配置的一部分進行安裝。
  • 可選:Docker Desktop,用於在 docker 中執行 redis-stack 進行本地測試。

執行 Redis Stack

有多種方法可以執行 Redis Stack。一種方法是使用 docker 映像:

docker run -d -p 6379:6379 -p 8001:8001 redis/redis-stack

建立專案

若要建立專案,只需執行:

dotnet new webapi -n Redis.OM.Skeleton --no-https --kestrelHttpPort 5000

然後在所選的 IDE 中開啟該檔案。Redis.OM.Skeleton.csproj

配置應用

向檔案新增欄位以配置應用程式。將該連線字串設定為 Redis 例項的 URI。如果使用前面提到的 docker 命令,則連線字串將為 。REDIS_CONNECTION_STRINGappsettings.jsonredis://localhost:6379

連線字串規範

Redis URI 的規範位於此處。可以將 或 用於不包含 的連線字串。:password@host:portdefault:password@host:portusername

建立模型

請確保將包新增到您的專案中。透過此軟體包,您可以輕鬆建立模型和查詢 Redis 域物件。Redis.OM

dotnet add package Redis.OM     

現在是時候建立應用程式將用於儲存/檢索人員的 / 模型了。建立一個名為的新目錄,並將檔案新增到其中。在 中,新增以下內容:PersonAddressModelAddress.csPerson.csAddress.cs

using Redis.OM.Modeling;

namespace Redis.OM.Skeleton.Model;

public class Address
{

    [Indexed]
    public int? StreetNumber { get; set; }

    

    [Indexed]
    public string? Unit { get; set; }

    

    [Searchable]
    public string? StreetName { get; set; }

    

    [Indexed]
    public string? City { get; set; }

    

    [Indexed]
    public string? State { get; set; }

    

    [Indexed]
    public string? PostalCode { get; set; }

    

    [Indexed]
    public string? Country { get; set; }

    

    [Indexed]
    public GeoLoc Location { get; set; }

}

在這裡,您會注意到,除了標記為 之外,所有欄位都使用該屬性進行修飾。這些屬性 ( 和 ) 告訴 Redis OM,您希望在 Redis Stack 中查詢文件時能夠在查詢中使用這些欄位。 不會是文件本身,所以頂級類不會用任何東西裝飾;相反,該模型將嵌入到我們的模型中。StreetNameSearchableIndexedSearchableIndexedAddressAddressPerson

為此,請將以下內容新增到Person.cs

using Redis.OM.Modeling;



namespace Redis.OM.Skeleton.Model;



[Document(StorageType = StorageType.Json, Prefixes = new []{"Person"})]

public class Person

{    

    [RedisIdField] [Indexed]public string? Id { get; set; }

    

    [Indexed] public string? FirstName { get; set; }



    [Indexed] public string? LastName { get; set; }

    

    [Indexed] public int Age { get; set; }

    

    [Searchable] public string? PersonalStatement { get; set; }

    

    [Indexed] public string[] Skills { get; set; } = Array.Empty<string>();    

    

    [Indexed(CascadeDepth = 1)] public Address? Address { get; set; }

    

}

這裡有幾點需要注意:

  1. [Document(StorageType = StorageType.Json, Prefixes = new []{"Person"})]指示 Redis OM 將用於在 Redis 中儲存文件的資料型別為 JSON,並且 Person 類的鍵的字首為 。Person

  2. [Indexed(CascadeDepth = 1)] Address? Address { get; set; }是使用 Redis OM 為嵌入物件編制索引的兩種方法之一。這種方式指示索引級聯到物件圖中的物件,1 表示它只會遍歷一個級別,索引物件就像從頭開始構建索引一樣。另一種方法使用要搜尋的各個索引欄位的屬性。這種更外科手術的方法限制了索引的大小。CascadeDepthJsonPath

  3. 該屬性被標記為 .這將欄位表示為儲存在 Redis 中時將用於生成文件鍵名稱的欄位。IdRedisIdField

建立索引

構建模型後,下一步是在 Redis 中建立索引。管理此問題的最正確方法是將索引建立旋轉到託管服務中,該服務將在應用程式啟動時執行。 建立一個目錄並新增到該目錄中。在該檔案中,新增以下內容,這將在啟動時建立索引。HostedServicesIndexCreationService.cs

using Redis.OM.Skeleton.Model;



namespace Redis.OM.Skeleton.HostedServices;



public class IndexCreationService : IHostedService

{

    private readonly RedisConnectionProvider _provider;

    public IndexCreationService(RedisConnectionProvider provider)

    {

        _provider = provider;

    }

    

    public async Task StartAsync(CancellationToken cancellationToken)

    {

        await _provider.Connection.CreateIndexAsync(typeof(Person));

    }



    public Task StopAsync(CancellationToken cancellationToken)

    {

        return Task.CompletedTask;

    }

}
接下來,新增以下內容以在啟動時註冊服務:Program.cs
builder.Services.AddHostedService<IndexCreationService>();

注入 RedisConnectionProvider

Redis OM 使用該類來處理與 Redis 的連線,並提供可用於與 Redis 互動的類。若要使用它,只需將 RedisConnectionProvider 的例項注入到應用中即可。在檔案中,新增:RedisConnectionProviderProgram.cs

builder.Services.AddSingleton(new RedisConnectionProvider(builder.Configuration["REDIS_CONNECTION_STRING"]));

這會將連線字串從配置中拉出並初始化提供程式。該提供程式現在可在您的控制器/服務中使用。

建立 PeopleController

最後一個難題是為我們的 People API 編寫實際的 API 控制器。在目錄中,新增檔案,該類的骨架將是:controllersPeopleController.csPeopleController

using Microsoft.AspNetCore.Mvc;

using Redis.OM.Searching;

using Redis.OM.Skeleton.Model;



namespace Redis.OM.Skeleton.Controllers;



[ApiController]

[Route("[controller]")]

public class PeopleController : ControllerBase

{



}

注入 RedisConnectionProvider

若要與 Redis 互動,請注入 RedisConnectionProvider。在此依賴注入過程中,拉出一個例項,該例項將允許在 Redis 中查詢文件的流暢介面。RedisCollection<Person>

private readonly RedisCollection<Person> _people;

private readonly RedisConnectionProvider _provider;

public PeopleController(RedisConnectionProvider provider)

{

    _provider = provider;

    _people = (RedisCollection<Person>)provider.RedisCollection<Person>();

}

新增用於建立人員的路由

新增到 API 的第一個路由是用於建立人員的 POST 請求,使用 ,就像呼叫 一樣簡單,傳入 person 物件:RedisCollectionInsertAsync

[HttpPost]

public async Task<Person> AddPerson([FromBody] Person person)

{

    await _people.InsertAsync(person);

    return person;

}

新增路由以按年齡篩選

要新增到 API 的第一個篩選器路由將允許使用者按最小和最大年齡進行篩選。使用 的 LINQ 介面是一個簡單的操作:RedisCollection

[HttpGet("filterAge")]

public IList<Person> FilterByAge([FromQuery] int minAge, [FromQuery] int maxAge)

{        

    return _people.Where(x => x.Age >= minAge && x.Age <= maxAge).ToList();

}

按地理位置篩選

Redis OM 有一個資料結構,其例項由模型索引,使用 ,可以使用該方法以及要過濾的欄位查詢具有特定位置半徑的所有物件:GeoLocAddressRedisCollectionGeoFilter

[HttpGet("filterGeo")]
public IList<Person> FilterByGeo([FromQuery] double lon, [FromQuery] double lat, [FromQuery] double radius, [FromQuery] string unit)
{
    return _people.GeoFilter(x => x.Address!.Location, lon, lat, radius, Enum.Parse<GeoLocDistanceUnit>(unit)).ToList();
}

按確切字串篩選

當模型中的字串屬性標記為 時,例如 並且,Redis OM 可以對它們執行精確的文字匹配。例如,以下兩個按 和 name 篩選的路由演示了完全匹配的字串。IndexedFirstNameLastNamePostalCode

[HttpGet("filterName")]
public IList<Person> FilterByName([FromQuery] string firstName, [FromQuery] string lastName)
{
    return _people.Where(x => x.FirstName == firstName && x.LastName == lastName).ToList();
}



[HttpGet("postalCode")]
public IList<Person> FilterByPostalCode([FromQuery] string postalCode)
{
    return _people.Where(x => x.Address!.PostalCode == postalCode).ToList();
}

當模型中的屬性標記為 、 和 時,您可以執行全文搜尋,請參閱 和 的篩選器:SearchableStreetAddressPersonalStatementPersonalStatementStreetAddress

[HttpGet("fullText")]
public IList<Person> FilterByPersonalStatement([FromQuery] string text)
{
    return _people.Where(x => x.PersonalStatement == text).ToList();
}



[HttpGet("streetName")]
public IList<Person> FilterByStreetName([FromQuery] string streetName)
{
    return _people.Where(x => x.Address!.StreetName == streetName).ToList();
}

按陣列成員資格篩選

當字串陣列或列表標記為 時,Redis OM 可以使用陣列或列表的方法過濾包含給定字串的所有記錄。例如,我們的模型有一個技能列表,您可以透過新增以下路由來查詢。IndexedContainsPerson

[HttpGet("skill")]
public IList<Person> FilterBySkill([FromQuery] string skill)
{
    return _people.Where(x => x.Skills.Contains(skill)).ToList();
}

更新人員

使用 Redis OM 更新 Redis Stack 中的文件可以透過以下方法完成:首先具體化 person 物件,進行所需的更改,然後呼叫集合。該集合負責跟蹤對其中實現的實體所做的更新;因此,它將跟蹤並應用您在其中所做的任何更新。例如,新增以下路由以更新給定 ID 的人員的年齡:Save

[HttpPatch("updateAge/{id}")]
public IActionResult UpdateAge([FromRoute] string id, [FromBody] int newAge)
{
    foreach (var person in _people.Where(x => x.Id == id))
    {
        person.Age = newAge;
    }
    _people.Save();
    return Accepted();
}

刪除人員

可以從 Redis 中刪除文件。只需呼叫 Unlink,傳入金鑰名稱即可。給定一個 id,我們可以使用字首和 id 重建鍵名:Unlink

[HttpDelete("{id}")]
public IActionResult DeletePerson([FromRoute] string id)
{
    _provider.Connection.Unlink($"Person:{id}");
    return NoContent();
}

執行應用

現在剩下要做的就是執行應用程式並對其進行測試。您可以透過執行 來執行此操作,該應用程式現在暴露在埠 5000 上,並且應該有一個 swagger UI,您可以使用它來玩 API http://localhost:5000/swagger。有幾個指令碼以及一些資料檔案,用於使用 GitHub 儲存庫中的 API 將一些人插入到 Redis 中dotnet run

使用 Redis Insight 檢視資料

您可以安裝 Redis Insight GUI,也可以使用在 http://localhost:8001/ 上執行的 Redis Insight GUI。

您可以按照以下步驟檢視資料:

  1. 接受 EULA

Accept EULA

  1. 單擊“新增 Redis 資料庫”按鈕

Add Redis Database Button

  1. 輸入 redis 伺服器的主機名和埠名。如果您使用的是 docker 映像,則 this is and 為您的資料庫指定別名localhost6379

Configure Redis Insight Database

  1. 點選Add Redis Database.

相關文章