web随想笔记(二)
admin
2024-04-25 05:31:06
0

一、Spring Cache和Redis的区别

  1. Spring cache是代码级的缓存,一般是使用一个ConcurrentMap,也就是说实际上还是是使用JVM的内存来缓存对象的,这势必会造成大量的内存消耗。但好处是显然的:使用方便。
  2. Redis 作为一个缓存服务器,是内存级的缓存。它是使用单纯的内存来进行缓存。
  3. 集群环境下,每台服务器的spring cache是不同步的,这样会出问题的,spring cache只适合单机环境。
  4. Redis是设置单独的缓存服务器,所有集群服务器统一访问redis,不会出现缓存不同步的情况。
  1. 缓存级别不同
    Spring cache是代码级的缓存,他一般是使用一个ConcurrentMap。也就是说实际上还是是使用JVM的内存来缓存对象的,
    那么肯定会造成大量的内存消耗。但是使用方便。
    Redis 作为一个缓存服务器,是内存级的缓存。它是使用单纯的内存来进行缓存。

  2. sprirng cache+redis的好处

那么Spring cache +redis的好处显而易见了。既可以很方便的缓存对象,同时用来缓存的内存的是使用redis的内存,不会消耗JVM的内存,提升了性能。当然这里Redis不是必须的,换成其他的缓存服务器一样可以,只要实现Spring的Cache类,并配置到XML里面就行了。

  1. 集群环境下的springcache+redis

集群环境下,每台服务器的spring cache是不同步的,这样会出问题的,spring cache只适合单机环境redis是设置单独的缓存服务器,所有集群服务器统一访问redis,不会出现缓存不同步的情况spring cache是很早就有的东西,现在+redis是为了顺应时代,更好的兼容集群环境,加强保留spring cache功能,不如直接使用redis

二、Spring cache的基本原理:

​ 和 spring 的事务管理类似,spring cache 的关键原理就是 spring AOP,通过 spring AOP,其实现了在方法调用前、调用后获取方法的入参和返回值,进而实现了缓存的逻辑。

三、什么样的数据需要放进缓存呢?

把数据放入缓存,有三个标准:

  1. 数据量不大
  2. 访问频率高
  3. 数据更改频率低

四、为什么要使用SpringCache

先看一下我们使用缓存步骤:

  1. 查寻缓存中是否存在数据,如果存在则直接返回结果
  2. 如果不存在则查询数据库,查询出结果后将结果存入缓存并返回结果
  3. 数据更新时,先更新数据库
  4. 然后更新缓存,或者直接删除缓存

​ 此时我们会发现一个问题,所有我们需要使用缓存的地方都必须按照这个步骤去书写,这样就会出现很多逻辑上相似的代码。并且我们程序里面也需要显示的去调用第三方的缓存中间件的API,如此一来就大大的增加了我们项目和第三方中间件的耦合度。

​ 因此我们需要将查询缓存存入缓存这类似的代码封装起来用框架来替我们实现,让我们更好的去处理业务逻辑。那么我们如何让框架去帮我们自动处理呢,这不就是典型的AOP思想吗?

是的,Spring Cache就是一个这样的框架。它利用了AOP,实现了基于注解的缓存功能,并且进行了合理的抽象,业务代码不用关心底层是使用了什么缓存框架,只需要简单地加一个注解,就能实现缓存功能了。而且Spring Cache也提供了很多默认的配置,用户可以3秒钟就使用上一个很不错的缓存功能。

参考:

Spring Cache和Redis的区别

SpringCache整合Redis实现项目缓存解决方案

五、redis实现排行榜功能

​ 由于一个玩家名次上升x位将会引起x+1位玩家的名次发生变化(包括该玩家),如果采用传统数据库(比如MySQL)来实现排行榜,当玩家人数较多时,将会导致对数据库的频繁修改,性能得不到满足,所以我们只能另想它法。

redis的zset结构有着天然的排序功能,十分适合并发量大的排行功能。通过key值确定排行榜的范围,使用members来作为排序的标识,score作为排序的依据。

5.1 排行榜的key设计

排行榜一般按照时间段进行分类,分别有周榜月榜年榜。这样要区分不同的榜单就需要和时间关联上,通过时间判断来将数据都保存到对应的zset中。

例如年榜可以用年份来标识,今年的key就是2020,去年的key是2019。月榜的话通过月数来标识。周榜的情况有点特殊,可以通过当天处于本年的第几周来确定zset的key。这样设置的key为周数当,就可以统计当周的数据了

java中有直接获取周数的方法:

虽然可以快速获取到当天的所属周数,但是有的排行榜需要查看上一周的数据。那么上周周榜的key,即获取上一周的周数只需在本周的周数减去一就可以。

问题

假如今天是本年的第一周,那么上一周的周榜的key就等于0,显然这是不合理的。那么这个应该怎么处理呢?

其实本年的第0周就是上一年的最后一周,只需要获取到上一年的最后一周的周数就可以。所以第一步先把当前日期往前推7天在获取那天所属的周数,就可以解决跨年获取周数的问题。

5.2 ZSet同分排序规则

score相同的情况下,哪条数据会排在前面呢?

经查阅资料验证确实当score值相同时,按照member的字符顺序进行排列。

5.3 ZSet多字段排序

zset只能根据score进行排序,也就是单字段排序

既然只有一个排序字段,那么根据排序规则的权重重新组合这个数值。通过把权重高的数值放在组合数的最前面来达到数值比较上的优势。

score通过拼接获得,通过不同字段的重要性划分权重,从而把不同字段放到对应上的数位上的位置,这样就可以根据不同字段构造出不同大小的score,从而实现排序。

缺点:这个方法需要注意的点就是zset的score字段是double类型。在double类型中的数值类型,需要注意整数的精度和小数点精度。double能保存最多16位的数字,如果复合排序字段中有时间的话,用于其他字段排序的数字只有6位,这就是复合数值排序的限制之处。倒序排序的字段需要知道排名期间的最大值,才能进行取反

5.4 Redis数据备份

redis数据库属于内存性数据库,虽然速度快,也有持久化策略来保障高可用。但是大量的数据需要设置过期时间来腾出内存空间,所以需要通过定时任务将数据落到数据库中来保证数据,同时可以方便导出这些数据。实现起来也比较简单,通过当前所属周获取到redis的数据,对位落库就可以。

需要注意的就是定时任务的时间节点。为了保证本周的数据落库是最完整的数据,需要在下一周的第一次同步时再进行一次备份。这个时候就可以通过在redis中设置一个标志位,每次更新前判断是有上周数据已经同步的标志。(写时复制,RDB

参考

Redis实现排行榜设计

相关内容

热门资讯

历史上的5月8日发生了哪些事件... 历史上的5月8日发生了哪些事件?2020年5月8日,李清杉和黄芳迎牵小手谈恋爱
请问这是一部什么电影? 请问这是一部什么电影?预见未来?
问一本世界名著的名字 问一本世界名著的名字《小妇人》吧。看过的书里这本最符合了。希望可以帮助到您。悲惨世界是不是
形容人自律的成语 形容人自律的成语严于律己成语发音:yán yú lǜ jǐ成语解释:律:约束。严格地约束自己。形容对...
阿泽是什么? 阿泽是什么?别埋汰狗好不好!!
生人勿扰!免得伤其无孤的意思 生人勿扰!免得伤其无孤的意思生人勿扰:直译--不认识的陌生人不要前来打扰。其实是不欢迎不认识的人,不...
历史上甄宓真的与大小乔并称当世... 历史上甄宓真的与大小乔并称当世三大美人吗?江东有二乔,河北甄宓俏。”这句话出自哪里?史书上写了吗?那...
龙血战神女主角是谁? 龙血战神女主角是谁?女主角:灵曦龙辰的老婆是女主角,名字是灵曦。
原创 民... 在6月29日,南宁民族影城IMAX激光影厅的启幕仪式如火如荼地进行,这座备受影迷期待的IMAX激光影...
村里新建文化礼堂,求对联一副! 村里新建文化礼堂,求对联一副!上联后字开头,下联塘字开头,谢谢!曾氏礼堂落成后来居上勤学苦练知识广塘...
英语在线翻译 小朋友 英语在线翻译 小朋友英语在线翻译 小朋友中文:小朋友=英文:Children
易拉罐小制作怎么做 易拉罐小制作怎么做要简单滴简单明了,很简单吧
把人挤出底线,算犯规吗? 把人挤出底线,算犯规吗?不算 不过动作幅度过大有可能就算了不算 但不要故意往底线整 人家站0度三...
这才是煎豆腐最好吃的家常做法,... 周末傍晚,隔壁厨房飘来一阵勾人的焦香,混着一点辛辣的诱惑。我忍不住探出头,只见楼下王姨正端着盘金黄微...
感冒吃药上瘾怎么办? 感冒吃药上瘾怎么办?戒掉...那是一件很严重的事情,现在市面上的感冒药大多都有抗生素,抗生素是治病的...
你觉得你会如何度过生命中最后的... 你觉得你会如何度过生命中最后的时光?生命的结束是人生旅途的最后部分,如果知道明天终将离去,那么,回头...
怀君属秋夜,散步咏凉天的含义 怀君属秋夜,散步咏凉天的含义《秋夜寄邱员外》作者:韦应物怀君属秋夜,散步咏凉天。空山松子落,幽人应未...
忽然觉得自己很累,有人说生活就... 忽然觉得自己很累,有人说生活就像一场梦亦真亦假,难道真的如此嘛?其实生活不是一场梦,只是我们太不懂稿...
关于和好朋友发生争执的作文 关于和好朋友发生争执的作文如果你觉得作文题目有什么不适合你的题意,你可以自己再重新定,仅供参考   ...