游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

SpringDataRedis两个问题内存泄露和并发euro

  我们最近将会话管理从MongoDB迁移到了Redis。迁移本身是由我们使用MongoDB的经验推动的,它不能特别好地处理高频率更新和更频繁地读取。另一方面,Redis被称为经过验证的存储,可以准确处理该用例。
  数据库迁移并不总是那么容易,因为我们需要学习其他服务的新模式、最佳实践和怪癖。我们的目标是让我们的Java服务层尽可能简单,使其稳定且面向未来:会话管理当然是具有相当稳定功能集的服务之一,并且不会经常触及其代码。因此,对于几年后窥探它的任何人来说,保持它的简单易懂是一个重要方面。
  我们面临两个问题:SpringData实现二级索引的概念以及失效问题,这些导致Redis内存使用量不断增长。Redis的原子性范围和SpringData的更新机制
  本文总结了我们在使用SpringData作为持久层的瘦Java服务中采用Redis的经验。
  带有二级索引和EXPIRETTL的SpringDataRedis
  在Redis中采用SpringData可直接开始:您需要的只是Gradle或Maven构建的依赖项以及EnableRedisRepositoriesSpringBoot应用程序中的注释。SpringBoot的大多数默认设置都是有意义的,并且可以让您非常顺利地运行Redis实例。
  但是会遭遇:Redis内存使用量不断增长的问题,下面看看这个认识过程:
  不需要通用存储库的实际实现,因为SpringData允许您interface在运行时声明一个简单的通向通用实例。我们的存储库是这样开始的:bimportborg。springframework。data。repository。CrudRepository;bimportborg。springframework。stereotype。Repository;RepositorybpublicbbinterfacebSessionDataCrudRepositorybextendsbCrudRepositorySessionData,String{}
  我们由该存储库管理的实体也开始变得尽可能简单:bimportborg。springframework。data。annotation。Id;bimportborg。springframework。data。redis。core。RedisHash;bimportborg。springframework。data。redis。core。TimeToLive;bimportbjava。util。concurrent。TimeUnit;RedisHash(fontSessionDatafontfont)bpublicbbclassbSessionData{IdbprivatebStringsessionId;TimeToLive(unitTimeUnit。MINUTES)bprivatebLongttl;。。。}font
  您会注意到我们选择对ttl属性建模,该属性被TimeToLive转换为EXPIRE实体。我们不想手动跟踪过期会话,但希望Redis透明地删除过期会话。该ttl会定期刷新用户活动期间,如果手工删除,可能会被注销。
  当用户实际按下注销按钮时会发生什么,或者我们如何禁用用户帐户并使正在运行的会话无效?简单:我们也有一个userId作为会话数据SessionData的一部分,并且可以执行以userId查询查找每个会话。上述类型所需的更改如下所示:
  SessionDataCrudRepository:RepositorybpublicbbinterfacebSessionDataCrudRepositorybextendsbCrudRepositorySessionData,String{ListSessionDatafindByUserId(StringuserId);}
  SessionData:bimportborg。springframework。data。redis。core。index。Indexed;RedisHash(fontSessionDatafontfont)bpublicbbclassbSessionData{IdbprivatebStringsessionId;TimeToLive(unitTimeUnit。MINUTES)bprivatebLongttl;IndexedbprivatebStringuserId;。。。}font
  Indexed注解在SpringData中触发了一个特殊的行为:该注解实际上告诉SpringData在实体上创建和维护另一个索引,以便我们可以根据给定userId查询SessionData。
  但是,二级索引和实体自动到期的组合使设置变得更加复杂。当引用的实体被删除时,Redis不会自动更新二级索引,因此SpringData需要处理这种情况。
  然而,SpringData不会经常查询Redis的过期实体(键),这就是为什么SpringData依赖于RRedisKeyspaceNotificationsforexpiringkeys所谓的PhantomCopies(幻影副本)来失效过期键:
  当到期时间设置为正值时,将运行相应的EXPIRE命令。除了保留原始副本外,Redis中还保留了一个幻影副本,并设置为在原始副本之后5分钟过期。这样做是为了使Repository支持发布RedisKeyExpiredEvent,只要一个键过期expiringkey,就会在Spring的ApplicationEventPublisher中间保存过期的值,即使原始值已经被删除。
  下一段有一个小细节需要注意:
  默认情况下,初始化应用程序时禁用expiringkeys侦听器。可以在EnableRedisRepositories或RedisKeyValueAdapter中调整启动模式,以使用应用程序或在第一次插入具有TTL的实体时启动侦听器。有关可能的值,请参阅EnableKeyspaceEvents。
  遗憾的是,当时我们还没有阅读到这点。这就是为什么我们体验到启用EXPIRE禁用的expiringkeys侦听器以及不断增长的二级索引的效果的原因。长话短说:我们观察到越来越多的键和不断增长的内存使用量直到达到Redis的内存限制。
  检查Redis键可以很明显地找到配置错误的位置,最终启用键空间事件的注释EnableRedisRepositories使我们修复了内存泄露。
  我们还禁用了的自动服务器配置notifykeyspaceeventsproperty,因为我们在服务器端启用了该设置:bimportborg。springframework。data。redis。repository。configuration。EnableRedisRepositories;bimportbbstaticborg。springframework。data。redis。core。RedisKeyValueAdapter。EnableKeyspaceEvents。ONSTARTUP;EnableRedisRepositories(enableKeyspaceEventsONSTARTUP,keyspaceNotificationsConfigParameterfontfontfont)SpringBootApplicationbpublicbbclassbSessionManagementApplication{。。。}font
  我们还必须手动清理陈旧的数据,所以我们还要提一下,在处理大型数据集时,您应该总是更选择SCAN而不是KEYS。Netflix的nfdataexplorer可能会有所帮助,如果您不喜欢使用本机rediscli。
  并发读取和写入期间缺少实体
  随着内存使用量不断增长的问题得到解决,我们最终将新服务作为我们会话的主要来源。
  当请求击中我们的安全链时,我们总是验证用户的会话是否有效。这些验证是在会话管理中的简单查找sessionId。通常,404NOTFOUND会话管理的状态指示sessionId无效(未知)或会话已过期(并被Redis删除)。
  除了使用新API的应用程序中的一些相关更改外,我们还观察到了另一种奇怪的行为:无法找到某些会话,尽管我们100确定会话应该仍然有效(已知且未过期)。在会话查找失败后,大多数重试都成功了,所以我们知道数据没有丢失,只是无法找到。
  我们无法主动重现错误行为,收集日志、指标和跟踪也没有起到作用。在此过程中,我们添加了缓存和其他解决方法,并进行了一些更改以改进整体行为,但我们实际上并未解决该问题。
  如果您仔细阅读本文的第一部分,您可能还记得有关我们刷新ttl。我们不仅刷新ttl,而且还刷新作为SessionData的一部分lastResponse时间戳:RedisHash(fontSessionDatafontfont)bpublicbbclassbSessionData{IdbprivatebStringsessionId;TimeToLive(unitTimeUnit。MINUTES)bprivatebLongttl;bprivatebLocalDateTimelastResponse;IndexedbprivatebStringuserId;。。。}font
  因此,让我们更详细地了解有关会话管理的请求处理。用户发送一个请求,以及一个sessionId,表明他们已登录。我们使用它执行查找sessionId以验证用户的会话。如果会话被认为是有效的,则应用程序可以继续执行请求的操作。应用程序处理完请求后,安全链会定期更新会话,重置ttl和写入当前lastResponse时间戳。通常,用户执行多个请求可能不是真正的人,而是在浏览器中运行的前端应用程序。该前端应用程序并不真正关心它发送新请求的频率,因此我们可以假设多个请求可能同时到达我们的后端。
  正在验证多个请求。多个请求触发会话刷新以及SessionData的写操作。
  我们仍然使用SpringDataCrudRepository来读取和更新会话,使用以下代码:读:SessionDataCrudRepositoryrepository;bpublicbOptionalSessionDtogetSession(StringsessionId){OptionalSessionDatasessionrepository。findById(sessionId);。。。breturnbsession;}更新:SessionDataCrudRepositoryrepository;bpublicbOptionalLongrefreshSessionTtl(StringsessionId){OptionalSessionDatasessionrepository。findById(sessionId);AtomicLongupdatedTtlbnewbAtomicLong();session。ifPresent(data{data。setLastResponse(LocalDateTime。now(clock)。truncatedTo(SECONDS));data。setTtl(SESSIONTIMEOUT。toMinutes());SessionDatasavedrepository。save(data);updatedTtl。set(saved。getTtl());}breturnbOptional。of(updatedTtl。longValue());}
  有时,repository。findById(。。。)没有产生任何东西,所以我们专注于那部分。不过,问题是由repository。save(。。。)电话引发的。经过几周的谷歌搜索并盯着日志和跟踪,我们发现了refreshSessionTtl和getSession调用之间的相关性。
  互联网上的许多文章已经训练我们将Redis视为单线程服务,按顺序执行每个请求。谷歌搜索springdataredisconcurrentwrites,我们找到了stackoverflow和springprojectsspringdataredisissues1826中的问题,在那里描述甚至解释了我们的问题以及修复。
  长话短说:SpringData将更新实现为DEL和HMSET两个步骤时,没有任何事务保证。换句话说:通过CrudRepositories更新实体不提供原子性。我们的HGETALL请求有时恰好发生在DEL和之间HMSET,导致空结果,或者有时有结果,但结果为负ttl。
  我们的问题现在可以通过集成测试重现并使用PartialUpdate。
  所以上面的实现改为:KeyValueOperationskeyValueOperations;bpublicbOptionalLongrefreshSessionTtl(StringsessionId){OptionalSessionDatasessionrepository。findById(sessionId);AtomicLongupdatedTtlbnewbAtomicLong(3);session。ifPresent(data{PartialUpdateSessionDataupdatebnewbPartialUpdate(data。getSessionId(),SessionData。bclassb)。refreshTtl(btrueb)。set(fontttlfontfont,SESSIONTIMEOUT。toMinutes())。set(fontfontlastResponsefontfont,LocalDateTime。now(clock)。truncatedTo(SECONDS));keyValueOperations。update(update);OptionalSessionDatasavedrepository。findById(data。getSessionId());bifb(saved。isPresent()){updatedTtl。set(saved。get()。getTtl());}}breturnbOptional。of(updatedTtl。longValue());}font
  概括
  过期键、二级索引和将所有魔法委托给SpringDataRedis的组合需要正确配置键空间事件侦听器。否则,由于幻影副本,您使用的内存会随着时间的推移而增长。考虑EnableRedisRepositories(enableKeyspaceEventsONSTARTUP)在您的应用中使用类似的配置。
  在并发读取和更新的环境,提防SpringData的CrudRepository工具的更新的过程分为两个步骤DEL和HMSET。如果您观察到零星丢失的键或结果为负值TTL,则您可能遇到了并发问题。检查您的写入操作并考虑使用PartialUpdate和SpringData的RedisKeyValueTemplateupdate方法更新需要改变的属性。

课文大自然的秘密教学反思《大自然的秘密》这篇课文以作者一行人在海岛上所闻、所见、所做、所想为线索,描写了小海龟群离巢入海被食肉鸟啄食的惊心动魄的冲突场景。揭示了大自然万物都有生存之道,躲避灾难之本能的……IGN整理漫威宇宙电影烂番茄评分,排名第一是黑豹IT之家3月11日消息IGN在近日整理了迄今为止漫威电影宇宙所有影片在烂番茄上的评分排名。而出乎意料的是,漫威电影宇宙中一众好评的《钢铁侠》不敌《黑豹》,《黑豹》的烂番茄新鲜度……复仇者联盟4剪辑官宣完工,电影时长依旧未知IT之家3月9日消息近日,漫威宇宙电影《复仇者联盟4:终局之战》导演罗素兄弟在推特上表示,电影已经剪辑完成,但是影片长度尚未公布。据了解,将在四月底和五月初在全球市场上映。……惊奇队长烂番茄指数疑遭刷榜,或成漫威口碑最差电影IT之家3月9日消息近日,漫威旗下的超级英雄电影《惊奇队长》正在全球热映,目前国内票房已经达到三亿元,不过该片在电影评价网站烂番茄上却疑似被黑,观众评价即爆米花指数才40。……微信卖雨伞了!黑人问号表情很吸睛IT之家11月25日消息前天,微信官方商城WeStore又上线了一波新品,包括微信雨伞、微信卫衣和微信颈枕。其中微信雨伞包括三种配色款式,其中黑色的黑人问号雨伞是折叠晴雨……桂林山水的优秀教案设计教学要求通过看图、学文,了解桂林山水的特点,从而受到热爱祖国锦绣河山的教育,陶冶爱美情趣。学习作者细致观察和具体形象地描写景物的方法,培养观察、想象、理解、表达能力。学会……刘谦春晚同款魔术道具多色酒壶上架淘宝售价几千元IT之家2月5日消息时隔6年,刘谦在春晚上又带来了一项魔术表演魔壶,在春晚舞台现场,刘谦找了几名观众和自己完成了这个魔术,刘谦用一把壶倒出很多种不同的饮品震惊观众,不少人都想拥……高二英语MainlyampnbspRevision教案2科目英语年级高二文件high2unit12。doc标题mainlyrevision章节第十二单元关键词高二英语第十二单元内容一、教学目的和要求1。单词和词组:theotherd……今日秋分云清月秀,罗衫怯怯风露凉IT之家9月23日消息今天是农历二十四节气中的秋分,秋分之分为半之意,这是昼夜在春分之后又一次平分。阴阳相半,昼夜均衡,冷暖相宜,天气给人的感觉是比较舒适的。秋分的特点主……今日大暑,热得字都冒汗了IT之家7月23日消息今天是农历二十四节气之一的大暑,大暑节气正值三伏天,是一年中日照最多,气温最高的时期。《月令七十二候集解》中说:大暑,六月中不行,小编写不动了,热得字都冒……今日芒种青梅煮酒,夏暑菱歌雨漫漫IT之家6月6日消息今天时值芒种,农历二十四节气中的第九个节气,也是夏季的第三个节气。芒种,是麦类等有芒作物成熟的意思。《月令七十二候集解》:五月节,谓有芒之种谷可稼种矣,意指……今日立夏愿你生如夏花,温柔如初今天是5月6日,也是二十四节气当中的立夏属于夏季的第一个节气。立夏的到来,意味着我们已经来到了夏天。今年立夏在今天凌晨3时3分。通常每年5月5日或5月6日是公历的立夏。斗……
因发布时政有害信息,微博处置陆大千等8个头部账号IT之家10月2日消息据微博官方消息,为落实企业主体责任,严格贯彻执行《微博社区公约》《微博投诉操作细则》等社区管理规则中关于时政有害信息的规定,对微博内存在的时政有害信息和账……别出心裁的意思与造句别出心裁这个词我们经常会用到,下面是小编整理的别出心裁的意思与造句,欢迎阅读参考!别出心裁的意思:【成语】:别出心裁【拼音】:bichxnci【解释】:……交管12123AppiOS版2。6。4更新上线电子驾驶证功能感谢IT之家网友古筝王子的线索投递!IT之家5月31日消息据IT之家网友投稿,交管12123AppiOS版迎来2。6。4更新,此次更新主要新增了驾驶证电子版功能。除……微信支付推出外卖餐具套装等商品50套起售,售价66元IT之家9月30日消息上月底,微信支付服务商助手公众号发文宣布上线微信支付物料商城,向商家打包出售计算器、经营贴牌套装、招财营业挂牌amp;门贴、户外遮阳大伞以及展示小黑板等微……微信支付上线中秋花灯会活动可领提现免费券等今日,微信支付正式上线中秋花灯会活动,解锁节日新玩法,活动将于9月19日至9月21日限时开放。据介绍,用户打开微信支付有优惠小程序即可进入专区参加中秋花灯会活动,点亮各式……微信支付支付后推荐关注公众号功能9月1日起下线IT之家8月19日消息今日,财付通支付科技有限公司发布了《支付后推荐关注公众号功能下线通知》。通知指出,为了保障用户权益,提升用户使用体验,公司将于2021年9月1日起下……腾讯起诉倒置微信支付商标一审被驳回IT之家8月6日消息近日,腾讯科技(深圳)有限公司与国家知识产权局其他一审行政判决书公开。IT之家了解到,法院查明诉争商标为21824105号迷你过商标,腾讯诉称该商标与……小鸟找家小班游戏教案活动目标:1。学习故事中的对话语言别哭,别怕,我们来了我再也不怕天黑了。2。愿意帮助迷路的小鸟,大胆表述自己的想法。3。感受遇到困难时获得帮助和关爱的情感,愿……初一英语教学反思初一的英语该怎么教?课后该怎么反思?下面是由小编为大家带来的关于初一英语教学反思,希望能够帮到您!篇一:初一英语教学反思我认为,英语教学的目的主要是培养学生掌握并运……抖音回应腾讯扫黑风暴相关投诉已下架被投诉视频超8000个IT之家8月21日消息今日晚间,抖音通过官方微博发布了对腾讯《扫黑风暴》相关投诉的处理说明。IT之家了解到,抖音表示,近日,腾讯公司对抖音发起侵权诉讼,称其独播电视剧《扫……快手打击饭圈乱象再处置违规视频33958条,违规帐号175个IT之家8月27日消息今日,快手官方公布了新一期关于开展清朗饭圈乱象整治的专项打击公告。快手表示,为落实清朗‘饭圈’乱象整治专项行动要求,快手自6月15日起对饭圈乱象开展……继CBA东京奥运会之后,快手正与NBA洽谈战略合作IT之家8月27日消息继CBA、东京奥运会之后,快手目前正在与NBA就结为战略合作关系进行沟通,双方计划从内容及品牌商业化等方面全面合作。据悉,在内容层面,快手将持有NB……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网