Spring Boot Redis 叢集效能最佳化(基於 Redisson)

Jason207010發表於2024-07-08
  • 1. Spring Boot Redis 叢集效能最佳化(基於 Redisson)
    • 1.1. 版本說明
    • 1.2. 為什麼是 Redisson
    • 1.3. 引數最佳化
      • 1.3.1. Redisson 配置引數
        • 1.3.1.1. 通用引數
        • 1.3.1.2. 叢集引數
        • 1.3.1.3. 最終引數配置
    • 1.4. 從 Nacos 獲取 Redisson 配置

1. Spring Boot Redis 叢集效能最佳化(基於 Redisson)

1.1. 版本說明

構件 版本
spring-boot 2.6.13
spring-cloud 2021.0.5
spring-cloud-alibaba 2021.0.5.0
redisson-spring-boot-starter 3.29.0
redisson-spring-data-26 3.29.0

1.2. 為什麼是 Redisson

Redisson 提供了 Lettuce、Jedis 等 Java 客戶端的所有功能,同時還提供了更豐富的分散式功能,並且與 Spring Boot、Hibernate、MyBatis 等更多框架無縫整合。

Redisson vs Jedis

Redisson vs Lettuce

1.3. 引數最佳化

redisson-spring-boot-starter 支援 3 種配置方式:

  1. 基於 org.springframework.boot.autoconfigure.data.redis.RedisProperties 類配置。
  2. spring.redis.redisson.config 指定 Redisson 自身的配置文字。
  3. spring.redis.redisson.file 指定 Redisson 自身的配置檔案位置。

方式 1 只能配置少數 Redis 引數,其他執行緒數量、超時時間等關鍵引數無法配置,只適用於開發環境使用;
方式 2 指定了一長串 yaml 配置字串,不易閱讀和配置;
方式 3 指定了一個本地 yaml 配置檔案,對於很多使用 Nacos 作為配置中心的專案來說非常不方便;

以上 3 種方式都不適合在專案中使用,因此後續會在方式 3 專案上進行改造,使支援從 Nacos 讀取配置。

1.3.1. Redisson 配置引數

1.3.1.1. 通用引數

  1. threads:執行緒池數量。這個執行緒池數量被所有 RTopic 物件監聽器,RRemoteService 呼叫者和 RExecutorService 任務共同共享。預設值:16。
  2. nettyThreads:Netty 執行緒池數量。這個執行緒池數量是在一個 Redisson 例項內,被其建立的所有分散式資料型別和服務,以及底層客戶端所一同共享的執行緒池裡儲存的執行緒數量。預設值:32。
  3. nettyExecutor:Use external ExecutorService which is used by Netty for Redis response decoding and command sending. 預設值:null。
  4. codec:Redisson 的物件編碼類是用於將物件進行序列化和反序列化,以實現對該物件在 Redis 裡的讀取和儲存。預設值:!<org.redisson.codec.Kryo5Codec> {}
  5. executor:單獨提供一個用來執行所有 RTopic 物件監聽器,RRemoteService 呼叫者和 RExecutorService 任務的執行緒池(ExecutorService)例項。預設值:null。
  6. transportMode:傳輸模式。預設值:NIO。
  7. eventLoopGroup:用於特別指定一個 EventLoopGroup. EventLoopGroup 是用來處理所有透過 Netty 與 Redis 服務之間的連線傳送和接受的訊息。每一個 Redisson 都會在預設情況下自己建立管理一個 EventLoopGroup 例項。因此,如果在同一個 JVM 裡面可能存在多個 Redisson 例項的情況下,採取這個配置實現多個 Redisson 例項共享一個 EventLoopGroup 的目的。預設值:null。
  8. lockWatchdogTimeout:監控鎖的看門狗超時時間單位為毫秒。該引數只適用於分散式鎖的加鎖請求中未明確使用 leaseTimeout 引數的情況。如果該看門口未使用 lockWatchdogTimeout 去重新調整一個分散式鎖的 lockWatchdogTimeout 超時,那麼這個鎖將變為失效狀態。這個引數可以用來避免由 Redisson 客戶端節點當機或其他原因造成死鎖的情況。預設值:30000。
  9. checkLockSyncedSlaves:Defines whether to check synchronized slaves amount with actual slaves amount after lock acquisition。預設值:true。
  10. slavesSyncTimeout:Defines slaves synchronization timeout in milliseconds applied to each operation of RLock, RSemaphore, RPermitExpirableSemaphore objects。預設值:1000。
  11. reliableTopicWatchdogTimeout:Reliable Topic watchdog timeout in milliseconds. Reliable Topic subscriber expires after timeout if watchdog didn't extend it to next timeout time interval. This prevents against infinity grow of stored messages in topic due to Redisson client crush or any other reason when subscriber can't consumer messages anymore。預設值:600000。
  12. keepPubSubOrder:透過該引數來修改是否按訂閱釋出訊息的接收順序出來訊息,如果選否將對訊息實行並行處理,該引數只適用於訂閱釋出訊息的情況。預設值:true。
  13. useScriptCache:Defines whether to use Lua-script cache on Redis side. Most Redisson methods are Lua-script based and this setting turned on could increase speed of such methods execution and save network traffic。預設值:false。
  14. minCleanUpDelay:Defines minimum delay in seconds for clean up process of expired entries. Applied to JCache, RSetCache, RClusteredSetCache, RMapCache, RListMultimapCache, RSetMultimapCache, RLocalCachedMapCache, RClusteredLocalCachedMapCache objects.。預設值:5。
  15. maxCleanUpDelay:Defines maximum delay in seconds for clean up process of expired entries. Applied to JCache, RSetCache, RClusteredSetCache, RMapCache, RListMultimapCache, RSetMultimapCache, RLocalCachedMapCache, RClusteredLocalCachedMapCache objects.。預設值:1800。
  16. cleanUpKeysAmount:Defines expired keys amount deleted per single operation during clean up process of expired entries. Applied to JCache, RSetCache, RClusteredSetCache, RMapCache, RListMultimapCache, RSetMultimapCache, RLocalCachedMapCache, RClusteredLocalCachedMapCache objects.。預設值:100。
  17. nettyHook:Netty hook applied to Netty Bootstrap and Channel objects.。預設值:!<org.redisson.client.DefaultNettyHook> {}
  18. connectionListener:Connection listener which is triggered when Redisson connected/disconnected to Redis server。預設值:null。
  19. useThreadClassLoader:Defines whether to supply Thread ContextClassLoader to Codec. Usage of Thread.getContextClassLoader() may resolve ClassNotFoundException error arise during Redis response decoding. This error might arise if Redisson is used in both Tomcat and deployed application。預設值:true。
  20. addressResolverGroupFactory:Allows to specify customized implementation of io.netty.resolver.dns.DnsAddressResolverGroup。預設值:!<org.redisson.connection.SequentialDnsAddressResolverFactory> {}
    Available implementations:
    • org.redisson.connection.DnsAddressResolverGroupFactory - uses default DNS servers list provided by OS.
    • org.redisson.connection.SequentialDnsAddressResolverFactory - uses default DNS servers list provided by OS and allows to control concurrency level of requests to DNS servers.
    • org.redisson.connection.RoundRobinDnsAddressResolverGroupFactory - uses default DNS servers list provided by OS in round robin mode.
  21. lazyInitialization:Defines whether Redisson connects to Redis only when first Redis call is made and not during Redisson instance creation。預設值:false。
    • true - connects to Redis only when first Redis call is made
    • false - connects to Redis during Redisson instance creation。
  22. protocol:Defines Redis protocol version. Available values: RESP2, RESP3。預設值:RESP2。

1.3.1.2. 叢集引數

叢集引數字首:clusterServersConfig

  1. idleConnectionTimeout:如果當前連線池裡的連線數量超過了最小空閒連線數,而同時有連線空閒時間超過了該數值,那麼這些連線將會自動被關閉,並從連線池裡去掉。時間單位是毫秒。預設值:10000。
  2. connectTimeout:同任何節點建立連線時的等待超時。時間單位是毫秒。預設值:10000。
  3. timeout:等待節點回覆命令的時間。該時間從命令傳送成功時開始計時。預設值:3000。
  4. subscriptionTimeout:Defines subscription timeout in milliseconds applied per channel subscription。預設值:7500。
  5. retryAttempts:如果嘗試達到 retryAttempts(命令失敗重試次數)仍然不能將命令傳送至某個指定的節點時,將丟擲錯誤。如果嘗試在此限制之內傳送成功,則開始啟用 timeout(命令等待超時)計時。預設值:3。
  6. retryInterval:在某個節點執行相同或不同命令時,連續 失敗 failedAttempts(執行失敗最大次數)時,該節點將被從可用節點列表裡清除,直到 reconnectionTimeout(重新連線時間間隔)超時以後再次嘗試。預設值:1500。
  7. password:用於節點身份驗證的密碼。預設值:null。
  8. username:Username for Redis server authentication. Requires Redis 6.0+。預設值:null。
  9. credentialsResolver:Defines Credentials resolver which is invoked during connection for Redis server authentication. Returns Credentials object per Redis node address, it contains username and password fields. Allows to specify dynamically changing Redis credentials。預設值:!<org.redisson.client.DefaultCredentialsResolver> {}
  10. subscriptionsPerConnection:每個連線的最大訂閱數量。預設值:5。
  11. clientName:在 Redis 節點裡顯示的客戶端名稱。預設值:null。
  12. sslEnableEndpointIdentification:開啟 SSL 終端識別能力。預設值:true。
  13. sslProvider:確定採用哪種方式(JDK 或 OPENSSL)來實現 SSL 連線。預設值:JDK。
  14. sslTruststore:Defines path to SSL truststore. It's stores certificates which is used to identify server side of SSL connection. SSL truststore is read on each new connection creation and can be dynamically reloaded。預設值:null。
  15. sslTruststorePassword:指定 SSL 信任證書庫的密碼。預設值:null。
  16. sslKeystore:Defines path to SSL keystore. It's stores private key and certificates corresponding to their public keys. Used if server side of SSL connection requires client authentication. SSL keystore is read on each new connection creation and can be dynamically reloaded。預設值:null。
  17. sslKeystorePassword:指定 SSL 鑰匙庫的密碼。預設值:null。
  18. sslProtocols:Defines array of allowed SSL protocols. Example values: TLSv1.3, TLSv1.2, TLSv1.1, TLSv1。預設值:null。
  19. pingConnectionInterval:This setting allows to detect and reconnect broken connections using PING command. PING command sending interval defined in milliseconds. Useful in cases when netty lib doesn't invoke channelInactive method for closed connections. Set 0 to disable。預設值:30000。
  20. keepAlive:Enables TCP keepAlive for connection。預設值:false。
  21. tcpKeepAliveCount:Defines the maximum number of keepalive probes TCP should send before dropping the connection. 0 value means use system default setting。預設值:0。
  22. tcpKeepAliveIdle:Defines the time in seconds the connection needs to remain idle before TCP starts sending keepalive probes. 0 value means use system default setting。預設值:0。
  23. tcpKeepAliveInterval:Defines the time in seconds between individual keepalive probes. 0 value means use system default setting。預設值:0。
  24. tcpUserTimeout:Defines the maximum amount of time in milliseconds that transmitted data may remain unacknowledged, or buffered data may remain untransmitted (due to zero window size) before TCP will forcibly close the connection. 0 value means use system default setting。預設值:0。
  25. tcpNoDelay:Enables TCP noDelay for connection。預設值:true。
  26. nameMapper:Defines Name mapper which maps Redisson object name to a custom name. Applied to all Redisson objects。預設值:!<org.redisson.api.DefaultNameMapper> {}
  27. commandMapper:Defines Command mapper which maps Redis command name to a custom name. Applied to all Redis commands。預設值:!<org.redisson.config.DefaultCommandMapper> {}
  28. loadBalancer:Сonnection load balancer for multiple Redis servers.。預設值:!<org.redisson.connection.balancer.RoundRobinLoadBalancer> {}
    Available implementations:
    • org.redisson.connection.balancer.CommandsLoadBalancer
    • org.redisson.connection.balancer.WeightedRoundRobinBalancer
    • org.redisson.connection.balancer.RoundRobinLoadBalancer
    • org.redisson.connection.balancer.RandomLoadBalancer
  29. slaveConnectionMinimumIdleSize:Redis 'slave' node minimum idle connection amount for each slave node。預設值:24。
  30. slaveConnectionPoolSize:Redis 'slave' node maximum connection pool size for each slave node。預設值:64。
  31. failedSlaveReconnectionInterval:Interval of Redis Slave reconnection attempt when it was excluded from internal list of available servers. On each timeout event Redisson tries to connect to disconnected Redis server. Value in milliseconds。預設值:3000。
  32. masterConnectionMinimumIdleSize:Minimum idle connections amount per Redis master node。預設值:24。
  33. masterConnectionPoolSize:Redis 'master' node maximum connection pool size。預設值:64。
  34. readMode:Set node type used for read operation。預設值:SLAVE。
    Available values:
    • SLAVE - Read from slave nodes, uses MASTER if no SLAVES are available,
    • MASTER - Read from master node,
    • MASTER_SLAVE - Read from master and slave nodes
  35. subscriptionMode:Set node type used for subscription operation。預設值:MASTER。
    Available values:
    • SLAVE - Subscribe to slave nodes
    • MASTER - Subscribe to master node
  36. subscriptionConnectionMinimumIdleSize:Minimum idle connection pool size for subscription (pub/sub) channels. Used by RTopic, RPatternTopic, RLock, RSemaphore, RCountDownLatch, RClusteredLocalCachedMap, RClusteredLocalCachedMapCache, RLocalCachedMap, RLocalCachedMapCache objects and Hibernate Local Cached Region Factories。預設值:1。
  37. subscriptionConnectionPoolSize:Maximum connection pool size for subscription (pub/sub) channels. Used by RTopic, RPatternTopic, RLock, RSemaphore, RCountDownLatch, RClusteredLocalCachedMap, RClusteredLocalCachedMapCache, RLocalCachedMap, RLocalCachedMapCache objects and Hibernate Local Cached Region Factories。預設值:50。
  38. dnsMonitoringInterval:Interval in milliseconds to check the endpoint's DNS. Applications must ensure the JVM DNS cache TTL is low enough to support this. Set -1 to disable。預設值:5000。
  39. failedSlaveNodeDetector:Defines failed Redis Slave node detector object which implements failed node detection logic via org.redisson.client.FailedNodeDetector interface。預設值:!<org.redisson.client.FailedConnectionDetector> {}
    Available implementations:
    • org.redisson.client.FailedConnectionDetector - marks Redis node as failed if it has ongoing connection errors in defined checkInterval interval in milliseconds. Default is 180000 milliseconds.
    • org.redisson.client.FailedCommandsDetector - marks Redis node as failed if it has certain amount of command execution errors defined by failedCommandsLimit in defined checkInterval interval in milliseconds.
    • org.redisson.client.FailedCommandsTimeoutDetector - marks Redis node as failed if it has certain amount of command execution timeout errors defined by failedCommandsLimit in defined checkInterval interval in milliseconds.
  40. natMapper:Defines NAT mapper interface which maps Redis URI object and applied to all Redis connections. Can be used to map internal Redis server IPs to external ones. Available implementations: org.redisson.api.HostPortNatMapper and org.redisson.api.HostNatMapper。預設值:!<org.redisson.api.DefaultNatMapper> {}
  41. nodeAddresses:Add Redis cluster node or Redis endpoint addresss in host:port format. Redisson discovers automatically cluster topology. Use rediss:// protocol for SSL connection。預設值:null。
  42. scanInterval:Scan interval in milliseconds. Applied to Redis clusters topology scan。預設值:5000。
  43. checkSlotsCoverage:Enables cluster slots check during Redisson startup。預設值:true。
  44. shardedSubscriptionMode:Defines whether to use sharded subscription feature available in Redis 7.0+. Used by RMapCache, RLocalCachedMap, RCountDownLatch, RLock, RPermitExpirableSemaphore, RSemaphore, RLongAdder, RDoubleAdder, Micronaut Session, Apache Tomcat Manager objects。預設值:AUTO。

1.3.1.3. 最終引數配置

threads: 32
nettyThreads: 64
codec: !<org.redisson.codec.JsonJacksonCodec> {}
transportMode: "NIO"
checkLockSyncedSlaves: false
clusterServersConfig:
  idleConnectionTimeout: 60000
  connectTimeout: 10000
  timeout: 6000
  retryAttempts: 3
  retryInterval: 1500
  password: 123456
  pingConnectionInterval: 30000
  keepAlive: true
  tcpNoDelay: true
  subscriptionsPerConnection: 5
  clientName: demo
  loadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> {}
  slaveConnectionMinimumIdleSize: 24
  slaveConnectionPoolSize: 64
  masterConnectionMinimumIdleSize: 24
  masterConnectionPoolSize: 64
  subscriptionConnectionMinimumIdleSize: 1
  subscriptionConnectionPoolSize: 50
  failedSlaveReconnectionInterval: 3000
  readMode: "SLAVE"
  subscriptionMode: "MASTER"
  scanInterval: 15000
  nodeAddresses:
    - "redis://127.0.0.1:7001"
    - "redis://127.0.0.1:7002"
    - "redis://127.0.0.1:7003"
    - "redis://127.0.0.1:7004"
    - "redis://127.0.0.1:7005"
    - "redis://127.0.0.1:7006"

1.4. 從 Nacos 獲取 Redisson 配置

  1. 在 Nacos 控制檯頁面新增配置

    • 名稱空間:redisson-demo
    • Data ID:redisson-dev.yaml
    • Group:redisson-demo
    • 配置內容:參考上一章節“最終引數配置”
  2. 專案 application.yaml 配置

spring:
  application:
    name: redisson-demo
  profiles:
    active: dev
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        namespace: redisson-demo
        group: redisson-demo
        file-extension: yaml
      username: nacos
      password: nacos
  config:
    import: nacos:redisson-demo.yaml
  1. 從 Nacos 獲取配置例項化 RedissonClient
import com.alibaba.cloud.nacos.NacosConfigManager;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;

@Configuration
public class RedissonConfiguration {

    @Value("${spring.profiles.active}")
    private String profile;
    @Resource
    private NacosConfigManager nacosConfigManager;

    @Bean(destroyMethod = "shutdown")
    public RedissonClient redisson() throws Exception {
        String redissonYaml = nacosConfigManager.getConfigService().getConfig(String.format("redisson-%s.yaml", profile), "redisson-demo", 5000L);
        Config config = Config.fromYAML(redissonYaml);
        return Redisson.create(config);
    }
}

相關文章