redis除了redis缓存技术还可以做什么

点击阅读原文
Redis实现缓存,你应该懂的哪些思路!
日 发布,来源:
场景一:类似于微博,实现关注和被关注功能。
对每个用户使用两个集合类型键,用来存储关注别人的用户和被该用户关注的用户。当用户A关注用户B的时候,执行两步操作:
sadd user:A B
sadd user:B A
完成一次用户关注操作,需要执行两步代码,第一次实现用户A关注B,成为了B的粉丝。而第二步的时候,因为某种原因没有执行或执行成功,则A并不知道B关注了自己
事务的原理是,先将一个事务的命令发送给Redis,然后再让Redis依次执行这些命令。
一个事务中,要么都执行成功,要么都不执行
multi命令告诉redis准备介绍事务,先暂存起来,不要执行。然后发送需要一起执行的命令,最后exec结束事务,redis依次执行那么命令
如果在执行exec命令之前,因为某种原因,redis断掉了,Redis会清空事务队列.
有些时候,我们不仅需要通过事务来处理一些必须一起成功的动作,比如银行转账,从银行卡1转出钱到银行卡2,必须是都一起成功,不能说从银行卡1中扣完钱之后,没有进到银行卡2账上,两者动作比如都要完成。还有些时候,我们既要一起完成,也需要根据其中一步操作的结果来进行下一步操作
watch,事务中的另一个命令。监控一个或多个键,一旦其中一个键被修改或删除,之后的事务就不会执行,一直到exec结束。
通过watch监控key1,之后修改了key1,所以事务中的set命令并没有执行
场景二:限时活动,缓存,验证码失效
在实际开发中,经常会遇到限时活动,邮箱失效时间,验证码失效时间等场景,这些数据需要在一定的时间内有效,过期删除,如果在关系型数据库中保存这些数据,每次校验都需要查询数据,对比时间,然后将数据置为失效,或者删除。而在Redis中,则可以通过expire设置失效时间,自动删除。
expire设置失效时间,时间单位秒。成功返回1,如果key不存在返回0
当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。
注意:在 Redis 2.8 以前,当 key 不存在,或者 key 没有设置剩余生存时间时,命令都返回 -1
为了提供网站的负载能力,需要将一个访问频路较高,且经过复杂计算或者IO资源消耗较大的操作的结果缓存起来,并设置一个失效时间。每次用户访问的时候,先检查该键是否存在,如果存在直接获取该元素并返回,如果不存在,则经过一系列计算并将结果缓存,设置失效时间,在返回给用户
这种缓存的实现,显然会有两个问题,第一个是缓存都是存在内容中的,如果大量的使用缓存会导致Redis沾满内存,另一方面,为了防止Redis沾满内存而设置失效时间的键,如果设置时间太短,就可能导致缓存命中率过低并且大量内容白白浪费。
使用方式:
在开发中,很难合理的设置键的生存时间,所以可以限制Redis使用的最大内存,并让Redis按照一定规则删除一些不需要的键。
具体方式,修改配置文件的maxmemory参数
OS X下通过Homebrew安装的redis的话,配置文件在/usr/local/etc/redis.conf
限制Redis最大内存之后,当超出了这个内存,会根据maxmemory-policy
指定的参数删除不需要的键。当设置此参数为allkeys-lru,一旦Redis内存超过了限制值时,Redis会不断删除数据库中最近最少使用的键,直到满足了当前内存大小限制
我要该,理由是:
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)博客分类:
最近集群上有个job,其中需要短时间内频繁访问缓存,大概7亿多次。我这边的缓存是使用redis来做的,问题就来了。
首先,redis中存的是普通kv,没有考虑使用hash等解结构,那么以为着这个job需要访问7亿多次redis,导致效率低,且出现很多redis的read timeout exception.
我采取的一些办法:
1、使用pool来管理连接,并且适当放长timeout的时间,切记在每次使用完连接后放回池中。
2、把不同业务的缓存放到不同的redis实例上,效率有一定增加。
3、这个job访问的缓存有个特点,数据量不大,总共才几十兆,所以决定在每个node上使用map来保存,在reduce初始化阶段就读进去,效率有较大提升。
4、使用redis的pipeline,一次性将所有缓存拉过来,效率非常好。(注意这里需要你获取缓存值之间没有依赖)
此外,我也是用了hadoop的DistributedCache来处理,效果也还过得去,但是我始终对这个方式没好感,最大的体会是不灵活,特别是在有向缓存服务器反设值的时候,此方式无效。
chenchao051
浏览: 67304 次
来自: 杭州
还没细看,似乎取材自一本书《scala与clojure设计模式 ...
补充,我代码中监听了session失效事件,并做了重连,但重连 ...
请问这一般是什么原因引起的呢?怎么解决?我被这个问题困扰几个星 ...
耶 耶 耶 耶 耶 耶 耶 耶 耶 耶 耶 耶 耶 耶 耶 耶 ...
唉.唉.唉.唉.唉.唉.唉.唉.唉.唉.唉.唉.唉.唉.唉.
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'使用redis和fastjson做应用和mysql之间的缓存
第一次做这种javaweb的项目,难免还是要犯很多错误。
大概也知道,redis常常被用来做应用和mysql之间的缓存。模型大概是这样子的。
为了让redis能够缓存mysql数据库中的数据,我写了很多这样类似的代码:
原来的查询商品
public Product selectProductById(int id) {
Product product = productMapper.
第一次做这种javaweb的项目,难免还是要犯很多错误。
大概也知道,redis常常被用来做应用和mysql之间的缓存。模型大概是这样子的。
为了让redis能够缓存mysql数据库中的数据,我写了很多这样类似的代码:
原来的查询商品
public Product selectProductById(int id) {
Product product = productMapper.selectByPrimaryKey(id);
if (product != null) {
String detail = product.getDetail();
if (detail != null) {
product.setDetail(HtmlUtils.string2Html(detail));// 进行html转义,替换html转义符
用redis缓存之后的查询商品
public Product selectProductById(int id) {
Product product = JSONObject.parseObject(redisCli.get(PRODUCT_KEY +
id), Product.class);
if (product != null) {
product = productMapper.selectByPrimaryKey(id);
String detail = product.getDetail();
if (detail != null) {
product.setDetail(HtmlUtils.string2Html(detail));// 进行html转义,替换html转义符
redisCli.set(PRODUCT_KEY + product.getId(), JSONObject.toJSON(product).toString(),
老板说,不行啊,网站首页太慢了!于是我们又开始在ModelAndView上做文章。
原来首页的代码
@RequestMapping("/wxIndex/{id}")
public ModelAndView goWxIndex(HttpServletRequest request, HttpServletResponse response,
@PathVariable(value = "id") Integer id) {
ModelAndView mv = new ModelAndView();
mv.setViewName(ViewNameConstant.WXINDEX);
//一些逻辑代码
于是我们又加了这样的代码:
@RequestMapping("/wxIndex/{id}")
public ModelAndView goWxIndex(HttpServletRequest request, HttpServletResponse response,
@PathVariable(value = "id") Integer id) {
ModelAndView mv = JSONObject.parseObject(redisCli.get("index"),ModelAndView.class);
if(mv != null)
mv = new ModelAndView();
mv.setViewName(ViewNameConstant.WXINDEX);
//一些逻辑代码
redisCli.put("index",JSONObject.toString(mv),30);
于是代码越来越乱。
慢慢学习和适应spring的思想中,明白,我们可以使用拦截的方式去做mysql的缓存。我们拦截到一个sql语句,于是把这条sql语句作为key,把返回的结果作为value保存到redis里面去,失效时间为30秒钟;
期间如果发现一个有insert或者update就把对应表的所有的缓存给清理掉。
有了思想就下手去做好了。不曾想发现mybatis已经提供了对应好的缓存的接口Cache,思想和上述完全一致。
那么我们也就是用他的接口好了。
mybatis默认缓存是PerpetualCache,可以查看一下它的源码,发现其是Cache接口的实现;那么我们的缓存只要实现该接口即可。
该接口有以下方法需要实现:
public abstract interface Cache
String getId();
int getSize();
void putObject(Object key, Object value);
Object getObject(Object key);
Object removeObject(Object key);
void clear();
ReadWriteLock getReadWriteLock();
最重要的两个接口是putObject和getObject;任何select语句都会首先请求getObject函数,如果返回为null,那么再去请求mysql数据库;我们在mysql中取到数据之后,调用putObject函数,进行缓存数据的保存。
序列图为:
网上提供的案例,大部分是这样子:
public class MybatisRedisCache implements Cache {
private RedisCli redisC
public void putObject(Object key, Object value) {
logger.debug("&&&&&&&&&&&&&&&&&&&&&&&&putObject:"+key+"="+value);
redisCli.set(SerializeUtil.serialize(key.toString()), SerializeUtil.serialize(value));
public Object getObject(Object key) {
Object value = SerializeUtil.unserialize(redisCli.get(SerializeUtil.serialize(key.toString())));
logger.debug("&&&&&&&&&&&&&&&&&&&&&&&&getObject:"+key+"="+value);
public class SerializeUtil {
public static byte[] serialize(Object object) {
ObjectOutputStream oos =
ByteArrayOutputStream baos =
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
byte[] bytes = baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
public static Object unserialize(byte[] bytes) {
ByteArrayInputStream bais =
//反序列化
bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (Exception e) {
如果是通过java提供的序列化进行实体类和String的转换,那么我们要修改所有已经存在的实体Bean类,工作量太大;而且java的序列化效率又低;我们还是考虑使用工程已经引入的fastjson好;使用fastjson,就必须在缓存数据的时候,同时缓存数据的类型;我们使用redis的hash结构,就能解决这个问题
于是接口就成了下面这个样子:
public class MybatisRedisCache implements Cache {
private RedisCli redisC
public void putObject(Object key, Object value) {
String keyStr = getKey(key);
Map&String,String& map = new HashMap&String,String&();
//如果是多组数据,那么保存的方式不同,多组的情况需要保存子实体类型
if(value.getClass().equals(ArrayList.class))
@SuppressWarnings("unchecked")
List&Object& list = (List&Object&)
map.put("type", "java.util.ArrayList");
if(list.size() & 0)
map.put("subType", list.get(0).getClass().getCanonicalName());
map.put("subType",Object.class.getCanonicalName());
map.put("value", JSONObject.toJSONString(value));
map.put("type", value.getClass().getCanonicalName());
map.put("value", JSONObject.toJSONString(value));
this.redisCli.hAllSet(keyStr, map,30);
this.cacheKeys.add(keyStr);
public Object getObject(Object key) {
String keyStr = getKey(key);
Map&Object,Object& map = this.redisCli.hAllGet(keyStr);
String type = (String)map.get("type");
String value = (String)map.get("value");
if(type == null || value == null)
if("java.util.ArrayList".equals(type))
String subType = (String)map.get("subType");
return JSONObject.parseArray(value, Class.forName(subType));
return JSONObject.parseObject(value, Class.forName(type));
catch (Exception e)
e.printStackTrace();
public void clear() {
if(this.cacheKeys.isEmpty())
for(String key : this.cacheKeys)
this.redisCli.del(key);
this.cacheKeys.clear();
ps: 我们这里还是把key直接保存在了内存里面,这样存在的问题就是,如果服务器重启,那么需要清理所有的缓存;不然一定会造成脏数据。
或者,我们在保存缓存数据的时候,设置缓存数据的生命时间是30秒即可,希望对大家有所帮助。
版权声明:本文内容由互联网用户自发贡献,本社区不拥有所有权,也不承担相关法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至: 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
用云栖社区APP,舒服~
【云栖快讯】红轴机械键盘、无线鼠标等753个大奖,先到先得,云栖社区首届博主招募大赛9月21日-11月20日限时开启,为你再添一个高端技术交流场所&&
支持MySQL、SQL Server、PostgreSQL、MongoDB、Redis等关系型数据库和NoSQL...
一种稳定可靠、性能卓越、可弹性伸缩的数据库服务。基于飞天分布式系统和全SSD盘高性能存储,支持主备版和集群版两套...
MySQL 是全球最受欢迎的开源数据库,阿里云MySQL版 通过深度的内核优化和独享实例提供稳定极致的数据库性能...
为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效率,降低 IT 成本...
阿里云双11狂欢,不只是5折
Loading...2017年8月 Java大版内专家分月排行榜第三2017年4月 Java大版内专家分月排行榜第三2016年3月 Java大版内专家分月排行榜第三
2017年8月 Java大版内专家分月排行榜第三2017年4月 Java大版内专家分月排行榜第三2016年3月 Java大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。redis吧-百度贴吧--一款颠覆互联网的Nosql缓存--Redis颠覆了世界,我们要颠覆Redis,希望大家踊跃的将身边的朋友聚集到这里来!通过我们的创意和想法,把更多的知识传递给身边的每一个人。
签到排名:今日本吧第个签到,
本吧因你更精彩,明天继续来努力!
本吧排名:
本吧签到人数:20
可签7级以上的吧50个
本月漏签0次!
成为超级会员,赠送8张补签卡
连续签到:天&&累计签到:天
超级会员单次开通12个月以上,赠送连续签到卡3张
一款颠覆互联网的Nosql缓存
Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链
我在 Ubuntu 系统中安装了 redis 。开启 7 条爬虫,然后 redis 的占用内存一下子飙到 4 G,这是为什么呢?请问
/s/1c2hcqYW密码:x436
RedisDesktopManager 右边黑屏 怎么解决??? 如图: 进去之后也是黑屏状态,不能输入命令。
在简书上照着做的,redis主从+哨兵模式+漂移VIP做的redis高可用。可是我用java做测试,把redismaster宕机后,
Redis入门 以上教程关注“幻梦IT”微信公众号,回复 ‘ redis ’ 即可获得! 幻梦IT不定期分享资源! 爱学
目前项目中的一个接口需要进行redis模糊查询: 根据用户名查询出redis数据库中所有key里包含该用户名的条
这个方法获取zset值 jackson报错什么原因
大神们 谁做过redis+tomcat8 的session共享 求解惑啊
redis是master和slave之间只要执行复制就会执行快照,而master每次有写入命令都会执行复制,这样理解的话每
各位大神,最近在做一个项目,要分页,我的想法是先把数据查出来放到redis再从redis分页取出来,可是不
ShardedJedisClient api中没有提供清空所有缓存的方法,求教
使用spring整合的redis,可以正确查询和插入数据到redis数据库,但是用可视化工具查看数据库内容时都是诸
库存数据表,在mysql中已经做了分表存储,平均每个表大概2000w数据,页面访问数据已经无法接受了,现在
个人对redis没太多实际经验,想了一些问题,希望大神解答下,谢谢 如果一个商品库存10件 进行秒杀,为
各位大神能不能以一个简单的redis 框架讲解一下,我是个初学者,看框架看不懂
各位大神能不能以一个简单的redis 框架讲解一下,我是个初学者,看框架看不懂
直击活动现场|CRUG助力ODF 2017 开源数据库论坛:https://mp./s/ukk1Sbq3tcEZvGT8aQRY3Q
CRUG 携手 ACMUG 共同打造技术社区健康新模式:https://mp./s/1Bd-LQOA1o9C-4CbiY-Smg
CRUG 2017 上海活动报名地址:/event/775182
那个有redis的百度云视频,一起分享下,我最近想学习
php操作redis安装成功了,phpinfo也有redis模块,但php在页面中实例化redis类,却连接不上,什么原因
求大神指点 java 统计redis某段时间内每个命令的使用次数
开疆拓土:CRUG开创技术社区 + 户外活动新模式(带报名): https://mp./s/675BuYEHGxjg8FNrW85e0g
用最少的机器支撑万亿级访问微博6年Redis优化历程:/a/937638
近千节点的Redis Cluster高可用集群案例:优酷蓝鲸优化实战:/a/937638
饿了么Redis Cluster集群化演进:https://mp./s/NyJQisoFvG-f8KNsmMVkIQ
同程旅游缓存系统设计:如何打造Redis时代的完美体系(含PPT): https://mp./s/nO1vUMWpNcxl7D8UBnYyHA
视频回放链接如下: /dakashuo/playback/1210
如题,我的redis版本是window的
现在在redis中有一部分哈希表是这样命名的,比如,b:1代表id为1的书,b:2代表id为2的书。。。如此下去,现在我想统计一下redis中有多少本书,请问怎么
一个master两个slave,master挂掉之后,slave就夯在那里也不进行master选举 等到我再启动master,master又重新加入
原有redis添加节点172.31.176.126:7000,并将该节点设为主节点。但是到了move slot,敲完yes,就报了个错。请大
我在测试redis节点挂掉之后会不会出问题,结果,三台服务器中的一台的主从节点down掉之后,出现了两个
部署了redis集群,使用java jedisCluster连接,但是并发的时候,发现 jedisCluster 的setnx有的时候插入成功,但是
/s/1qXENYVy
你可能感兴趣的吧...
发贴红色标题
签到六倍经验
兑换本吧会员
赠送补签卡1张,获得
助攻总额: 43W
贴吧热议榜
发表后自动分享本贴
使用签名档&

我要回帖

更多关于 java缓存技术 redis 的文章

 

随机推荐