Garnet
概述
最近,Redis的開源協定更新引起了廣泛關註。作為記憶體數據結構儲存系統的佼佼者,Redis的每一次更新都對開發者社群產生深遠影響。在這種背景下,微軟推出了Garnet,這是一個旨在提供更高效能和穩定性的記憶體數據儲存解決方案。Garnet承諾維持開源原則,並致力於克服Redis在特定套用場景中可能遇到的效能限制,以滿足企業級數據處理的高標準要求。隨著Garnet的推出,開發者們現在有了更多的選擇,以適應不斷演進的技術環境和業務需求。
整體架構
核心優勢
相容性與易用性 :Garnet采用廣泛認可的RESP協定,使得現有的Redis客戶端無需修改即可無縫接入。
可延伸性與效能 :透過最佳化的客戶端連線和數據批次處理,Garnet在提升吞吐量的同時,降低了大型套用的執行成本。
低延遲與高穩定性 :Garnet在高百分位的延遲表現上更為出色,確保了關鍵業務場景的穩定性。
跨平台與現代化架構 :基於最新的.NET技術,Garnet不僅跨平台執行,而且易於開發和維護。它利用.NET生態系的豐富庫來擴充套件API,並提供了最佳化的機會,確保在Linux和Windows平台上均有卓越表現。
套用場景
Garnet適用於任何使用Redis、KeyDB或Dragonfly作為緩存儲存方案的應用程式。它能夠提供更高的吞吐量和更低的延遲,透過減少緩存儲存分片的數量來降低成本。此外,對於希望借助高效能緩存層來提升效能並減少後端儲存成本的新型應用程式,Garnet也是一個理想的選擇。
API 支持
Garnet支持廣泛的API功能,包括字串、分析和物件操作。它還提供了集群模式下的分片、復制和動態金鑰遷移等功能。Garnet支持客戶端RESP事務和用C#編寫的伺服器端儲存過程,同時允許使用者在字串和新物件型別上定義自訂操作,大大降低了自訂擴充套件的開發難度。
技術特性
Garnet采用快速且可延伸的網路層,支持包括內核旁路在內的後續擴充套件。它支持TLS通訊協定和基本存取控制。Garnet的儲存層Tsavorite源自OSS FASTER,提供了多層面的儲存支持(記憶體、SSD、雲端儲存等)、快速非阻塞檢查點、持久化操作、多鍵事務支持等高級資料庫功能。Garnet還支持集群操作模式,包括單節點和分片復制部署,以及高效的鍵遷移方案,使使用者能夠透過標準的Redis集群命令來管理Garnet集群。
套用
複制源碼
git clone https://github.com/microsoft/garnet.git
cd garnet
構建
docker build -t tinywan/garnet:v1 .
Sending build context to Docker daemon 30.26MB
Step 1/11 : FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
---> 60b36c949968
Step 2/11 : WORKDIR /source
---> Using cache
---> c13239cb3fbe
Step 3/11 : COPY . .
---> 91671e21cc3f
Step 4/11 : RUN dotnet restore
---> Running in 2c5e7c0dc757
Determining projects to restore...
Restored /source/libs/storage/Tsavorite/cs/src/devices/AzureStorageDevice/Tsavorite.devices.AzureStorageDevice.csproj (in 24.26 sec).
Restored /source/main/GarnetServer/GarnetServer.csproj (in 24.26 sec).
Restored /source/libs/storage/Tsavorite/cs/src/core/Tsavorite.core.csproj (in 9 ms).
Restored /source/libs/server/Garnet.server.csproj (in 18 ms).
Restored /source/libs/common/Garnet.common.csproj (in 5 ms).
Restored /source/libs/host/Garnet.host.csproj (in 26 ms).
Restored /source/libs/client/Garnet.client.csproj (in 6 ms).
Restored /source/libs/cluster/Garnet.cluster.csproj (in 21 ms).
Restored /source/benchmark/Resp.benchmark/Resp.benchmark.csproj (in 2.35 sec).
Restored /source/test/Garnet.test.cluster/Garnet.test.cluster.csproj (in 2.08 sec).
Restored /source/samples/MetricsMonitor/MetricsMonitor.csproj (in 4 ms).
Restored /source/samples/GarnetClientSample/GarnetClientSample.csproj (in 2 ms).
Restored /source/playground/TstRunner/TstRunner.csproj (in 4.61 sec).
Restored /source/playground/GarnetClientStress/GarnetClientStress.csproj (in 3 ms).
Restored /source/test/Garnet.test/Garnet.test.csproj (in 9.07 sec).
Restored /source/playground/Embedded.perftest/Embedded.perftest.csproj (in 12 ms).
Restored /source/playground/Bitmap/Bitmap.csproj (in 1 ms).
Restored /source/metrics/HdrHistogram/HdrHistogram.csproj (in 2 ms).
Restored /source/playground/ClusterStress/ClusterStress.csproj (in 1.54 sec).
Removing intermediate container 2c5e7c0dc757
---> 179d8ec5fb79
Step 5/11 : RUN dotnet build -c Release
---> Running in 0ef42fd483e5
MSBuild version 17.9.6+a4ecab324 for .NET
Determining projects to restore...
All projects are up-to-date for restore.
Garnet.common -> /source/libs/common/bin/AnyCPU/Release/net7.0/Garnet.common.dll
Garnet.common -> /source/libs/common/bin/AnyCPU/Release/net8.0/Garnet.common.dll
Garnet.common -> /source/libs/common/bin/AnyCPU/Release/net6.0/Garnet.common.dll
Tsavorite.core -> /source/libs/storage/Tsavorite/cs/src/core/bin/AnyCPU/Release/net6.0/Tsavorite.core.dll
Tsavorite.core -> /source/libs/storage/Tsavorite/cs/src/core/bin/AnyCPU/Release/net7.0/Tsavorite.core.dll
Tsavorite.core -> /source/libs/storage/Tsavorite/cs/src/core/bin/AnyCPU/Release/net8.0/Tsavorite.core.dll
Tsavorite.devices.AzureStorageDevice -> /source/libs/storage/Tsavorite/cs/src/devices/AzureStorageDevice/bin/AnyCPU/Release/net7.0/Tsavorite.devices.AzureStorageDevice.dll
Tsavorite.devices.AzureStorageDevice -> /source/libs/storage/Tsavorite/cs/src/devices/AzureStorageDevice/bin/AnyCPU/Release/net6.0/Tsavorite.devices.AzureStorageDevice.dll
Bitmap -> /source/playground/Bitmap/bin/Release/net7.0/Bitmap.dll
HdrHistogram -> /source/metrics/HdrHistogram/bin/AnyCPU/Release/net8.0/HdrHistogram.dll
HdrHistogram -> /source/metrics/HdrHistogram/bin/AnyCPU/Release/net7.0/HdrHistogram.dll
Garnet.client -> /source/libs/client/bin/AnyCPU/Release/net8.0/Garnet.client.dll
Resp.benchmark -> /source/benchmark/Resp.benchmark/bin/Release/net8.0/Resp.benchmark.dll
Garnet.client -> /source/libs/client/bin/AnyCPU/Release/net7.0/Garnet.client.dll
HdrHistogram -> /source/metrics/HdrHistogram/bin/AnyCPU/Release/net6.0/HdrHistogram.dll
Garnet.client -> /source/libs/client/bin/AnyCPU/Release/net6.0/Garnet.client.dll
Tsavorite.devices.AzureStorageDevice -> /source/libs/storage/Tsavorite/cs/src/devices/AzureStorageDevice/bin/AnyCPU/Release/net8.0/Tsavorite.devices.AzureStorageDevice.dll
Garnet.server -> /source/libs/server/bin/AnyCPU/Release/net8.0/Garnet.server.dll
Garnet.server -> /source/libs/server/bin/AnyCPU/Release/net6.0/Garnet.server.dll
Resp.benchmark -> /source/benchmark/Resp.benchmark/bin/Release/net6.0/Resp.benchmark.dll
ClusterStress -> /source/playground/ClusterStress/bin/Release/net6.0/ClusterStress.dll
ClusterStress -> /source/playground/ClusterStress/bin/Release/net7.0/ClusterStress.dll
Garnet.server -> /source/libs/server/bin/AnyCPU/Release/net7.0/Garnet.server.dll
Resp.benchmark -> /source/benchmark/Resp.benchmark/bin/Release/net7.0/Resp.benchmark.dll
ClusterStress -> /source/playground/ClusterStress/bin/Release/net8.0/ClusterStress.dll
GarnetClientStress -> /source/playground/GarnetClientStress/bin/Release/net8.0/GarnetClientStress.dll
GarnetClientSample -> /source/samples/GarnetClientSample/bin/Release/net8.0/GarnetClientSample.dll
Garnet.cluster -> /source/libs/cluster/bin/AnyCPU/Release/net7.0/Garnet.cluster.dll
MetricsMonitor -> /source/samples/MetricsMonitor/bin/Release/net7.0/MetricsMonitor.dll
Garnet.host -> /source/libs/host/bin/AnyCPU/Release/net7.0/Garnet.host.dll
GarnetServer -> /source/main/GarnetServer/bin/AnyCPU/Release/net7.0/GarnetServer.dll
Embedded.perftest -> /source/playground/Embedded.perftest/bin/Release/net7.0/Embedded.perftest.dll
Garnet.test.cluster -> /source/test/Garnet.test.cluster/bin/AnyCPU/Release/net7.0/Garnet.test.cluster.dll
Garnet.test -> /source/test/Garnet.test/bin/AnyCPU/Release/net7.0/Garnet.test.dll
TstRunner -> /source/playground/TstRunner/bin/Release/net7.0/TstRunner.dll
Garnet.cluster -> /source/libs/cluster/bin/AnyCPU/Release/net6.0/Garnet.cluster.dll
Garnet.host -> /source/libs/host/bin/AnyCPU/Release/net6.0/Garnet.host.dll
GarnetServer -> /source/main/GarnetServer/bin/AnyCPU/Release/net6.0/GarnetServer.dll
Embedded.perftest -> /source/playground/Embedded.perftest/bin/Release/net6.0/Embedded.perftest.dll
Garnet.test.cluster -> /source/test/Garnet.test.cluster/bin/AnyCPU/Release/net6.0/Garnet.test.cluster.dll
Garnet.test -> /source/test/Garnet.test/bin/AnyCPU/Release/net6.0/Garnet.test.dll
Garnet.cluster -> /source/libs/cluster/bin/AnyCPU/Release/net8.0/Garnet.cluster.dll
Garnet.host -> /source/libs/host/bin/AnyCPU/Release/net8.0/Garnet.host.dll
GarnetServer -> /source/main/GarnetServer/bin/AnyCPU/Release/net8.0/GarnetServer.dll
Embedded.perftest -> /source/playground/Embedded.perftest/bin/Release/net8.0/Embedded.perftest.dll
Garnet.test.cluster -> /source/test/Garnet.test.cluster/bin/AnyCPU/Release/net8.0/Garnet.test.cluster.dll
Garnet.test -> /source/test/Garnet.test/bin/AnyCPU/Release/net8.0/Garnet.test.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:02:22.04
Removing intermediate container 0ef42fd483e5
---> 46c099aeaef1
Step 6/11 : WORKDIR /source/main/GarnetServer
---> Running in 56e737ac9816
Removing intermediate container 56e737ac9816
---> 9b267c9979d2
Step 7/11 : RUN dotnet publish -c Release -o /app --self-contained false -f net8.0
---> Running in 0eb7ed8bafa7
MSBuild version 17.9.6+a4ecab324 for .NET
Determining projects to restore...
All projects are up-to-date for restore.
Garnet.common -> /source/libs/common/bin/AnyCPU/Release/net8.0/Garnet.common.dll
Tsavorite.core -> /source/libs/storage/Tsavorite/cs/src/core/bin/AnyCPU/Release/net8.0/Tsavorite.core.dll
HdrHistogram -> /source/metrics/HdrHistogram/bin/AnyCPU/Release/net8.0/HdrHistogram.dll
Tsavorite.devices.AzureStorageDevice -> /source/libs/storage/Tsavorite/cs/src/devices/AzureStorageDevice/bin/AnyCPU/Release/net8.0/Tsavorite.devices.AzureStorageDevice.dll
Garnet.client -> /source/libs/client/bin/AnyCPU/Release/net8.0/Garnet.client.dll
Garnet.server -> /source/libs/server/bin/AnyCPU/Release/net8.0/Garnet.server.dll
Garnet.cluster -> /source/libs/cluster/bin/AnyCPU/Release/net8.0/Garnet.cluster.dll
Garnet.host -> /source/libs/host/bin/AnyCPU/Release/net8.0/Garnet.host.dll
GarnetServer -> /source/main/GarnetServer/bin/AnyCPU/Release/net8.0/GarnetServer.dll
GarnetServer -> /app/
Removing intermediate container 0eb7ed8bafa7
---> f208788f85d3
Step 8/11 : FROM mcr.microsoft.com/dotnet/runtime:8.0
8.0: Pulling from dotnet/runtime
8a1e25ce7c4f: Already exists
d038975ffc90: Already exists
4d3bcc6169b1: Already exists
1b5cdfe08966: Already exists
e324257af4ea: Already exists
Digest: sha256:0eea5cbf81e777f83bc15a7df0348adb8e06ee229260bedbbbc8a6011ab67581
Status: Downloaded newer image for mcr.microsoft.com/dotnet/runtime:8.0
---> 0dfb7c186b84
Step 9/11 : WORKDIR /app
---> Running in 0dea6a33ad66
Removing intermediate container 0dea6a33ad66
---> 1b0414186874
Step 10/11 : COPY --from=build /app .
---> c50caeceede7
Step 11/11 : ENTRYPOINT ["/app/GarnetServer", "-i", "128m"]
---> Running in a53198dd3e37
Removing intermediate container a53198dd3e37
---> 2063100346b3
Successfully built 2063100346b3
Successfully tagged tinywan/garnet:v1
映像構建結果
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tinywan/garnet v1 2063100346b3 About a minute ago 206MB
啟動
docker run --rm -it -p 3278:3278 tinywan/garnet:v1
預設埠:
3278
映像結果
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0de9d3b549ac tinywan/garnet:v1 "/app/GarnetServer -…" 2 minutes ago Up 2 minutes
客戶端
直接使用
redis-cli
進行連結就可以啦!
$ redis-cli -p 3278
127.0.0.1:3278> keys *
(empty array)
127.0.0.1:3278> set tinywan "Hi 3278"
OK
127.0.0.1:3278> get tinywan
"Hi 3278"
伺服端版本
在使用 Redis 時,時常會遇到很多問題需要診斷,在診斷之前需要了解 Redis 的執行狀 態,透過強大的
info
指令,你可以清晰地知道 Redis 內部一系列執行參數。
透過
info
指令檢視Garnet伺服端版本資訊
garnet_version:1.0.1
127.0.0.1:3278> info
# Server
garnet_version:1.0.1
garnet_mode:standalone
os:Unix 4.15.0.137
processor_count:2
arch_bits:64
uptime_in_seconds:432.9138507
uptime_in_days:0.005010576975694445
monitor_task:disabled
monitor_freq:0
latency_monitor:disabled
run_id:6a6cba0771b63a236e152b2c661b4a323bc91a68
....
其他
127.0.0.1:3278> help keys
KEYS pattern
summary: Find all keys matching the given pattern
since: 1.0.0
group: generic
127.0.0.1:3278>
127.0.0.1:3278> help SADD
SADD key member [member ...]
summary: Add one or more members to a set
since: 1.0.0
group: set