当前位置: 欣欣网 > 码农

Redis高性能内存数据库替代品Garnet入门指南教程

2024-03-25码农

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