使用SpringBoot来支持Redis集群
太长不看.
-
- Redisへのセッション情報はapplication.yml に spring.session.store-type: redis、spring.redis.cluster.node: 接続先を設定するのみ
-
- 上記のみの場合、クラスターのスケールアップ・スケールアウトに対応できない
- スケールアップ・スケールアウトに対応するためにはapplication.ymlにspring.redis.lettuce.cluster.refresh.apaptive: true の設定が必要
背景和动机
在多个EC2实例上运行的SpringBoot应用程序的会话由每个EC2上的Tomcat进行管理。
每个用户的会话保持通过启用ALB的粘性会话来维持。
由于在频繁部署的时机,每个EC2都会与ALB断开连接,导致每次部署都会中断所有用户的会话。
通过将会话转换为单独的键值存储(Redis),以提高用户的便利性。
建筑师
稍后画图。
-
- AWS上で稼働しているサービス
-
- いわゆる三層アプリケーション
-
- CDN → WAF → ALB → EC2 → DB
- apache httpd/Tomcat/SpringBoot
有关KVS的信息
因为在AWS上运行,所以采用了Elasticache for Redis。虽然DynamoDB/Elasticache for Memcached也是可行的选择,但优先考虑了Redis的响应等因素。它可以进行备份,并包括了扩展和冗余的集群配置,以确保冗余和可用性。
让我们尝试连接到Redis。
只需在application.yml文件中进行以下设置,即可将会话信息迁移到Elasticache for Redis。
spring
session:
store-type: redis
redis:
configure-action: none
redis:
cluster:
nodes: xxxxxx.yyyyyy.clustercfg.apne1.cache.amazonaws.com:6379 # AWS構築したElasticache for Redis Clusterのエンドポイント。portは6379でよいはず
试试增加负载
为了验证,尝试增加负载。特定节点的负载增加,导致一些用户无法登录。
于是,添加分片。嗯?没有效果。
那就更改实例类型,进行扩容。嗯?嗯???没有收到响应????
页面一片空白??
应用完全无法连接..!!
重新启动Tomcat.. 终于恢复了服务.. 幸好是在验证环境中..
添加分片后,Tomcat以1/分片数的概率发生以下异常。
Caused by: io.lettuce.core.RedisException: java.io.IOException:
更改实例类型后,无法连接到任何Redis。
解决方案
看起来,初始设置可以连接到Redis集群,但是在增加分片或更改实例类型以进行集群内部配置更改时,似乎不会重新连接到端点后面的实际连接目标。
在SpringSession中进行Redis配置时,默认使用lettuce作为客户端。
lettuce默认关闭对集群的刷新设置。
通过在application.yml中添加以下设置,需要进行lettuce的刷新设置。
spring
session:
lettuce:
cluster:
refresh:
adaptive: true
period: 60s # 60sでとりあえずよさそう。要チューニング
当前情况
经过以上的设定,即使在执行实例类型更改、添加分片、删除分片之后,也可以在应用程序端实现无需重新启动Tomcat就不会发生错误。
目前,我们正在进行额外的负载测试以进行正式切换。