怎么清空redis缓存怎么弄

他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)基于sql实现redis主动缓存 - 为程序员服务
基于sql实现redis主动缓存
主要功能点
主动缓存,无异常情况下只从redis中取数据,不走mysql
列表的分类、排序
缓存数据中区分正在进行、未开始、已结束
分析sql语句触发redis缓存系统中数据的更新
对关联数据进行同步更新(例 广告中的数据里面有商品信息,当商品发生改变时,触发把广告中的相关商品数据内容也进行同步更新)
针对单个表的缓存数据重建功能
列表分页及排序主要依赖于redis 的sort 命令,通过配置来触发是否启用,是否同步关联数据等
数据存储结构
用redis 的 set (集合) 来保存ID号索引
用redis 的 hash(哈希) 来保存内容数据。Data为json结构化内容数据,同时hash内存入其它元素保存排序用的排序字段和内容
例: hset(data, json_encode($data))
hset(price, 100)
hset(sort, 1)
一个表中正在进行的主索引的key
(taobao_item 表示数据表表名, cate 表示存储的是主索引)
redisCache:taobao_item:cate
未开始ID号索引Key
redisCache:taobao_item: notstartids
已结束ID号索引 key
redisCache:taobao_item:endids
正在进行的分类索引Key set结构 cate_id表示分类的字段,最后面的1表示分类号,一个分类一个索引
redisCache:taobao_item:cate:cate_id:1
正在进行的内容Key (hash结构)
222表示是内容的ID号
redisCache:taobao_item:content:222
未开始的内容Key (hash结构)
redisCache:taobao_item:notstart:22
已结束的内容Key (hash结构)
redisCache:taobao_item:end:22
Sort redisCache:appmarket_app_commend:cate:cate_id:2
BY redisCache:appmarket_app_commend:content:*-&sort:sort
GET redisCache:appmarket_app_commend:content:*-&data
LIMIT 0 10
BY用于排序的Key,因为是hash结构,所以采用元素sort作为排序依据
GET 获取主内容,hash元素中的data 存储的是主内容的json结构化数据
LIMIT 分页,与mysql 的 limit作用方法一至
DESC 存在的话,为倒序,不存在的话为顺序
同步关联表数据
通过配置里的callback_sync_content 方法例如通过sql分析。监控到taobao_item发生update操作,因为设置了关联同步更新taobao_ad中的商品信息,所以触发,先从tabao_ad中通过回调配置中的get_id方法传入taoboa_item的主键ID号,得到tabao_ad中的主键ID,然后执行taobao_ad缓存的updateContent方法,从而实现关联更新taboa_ad中的相关数据
当数据过期时转存到已过期区域
基于用户触发
hash key也就是内容key会有一个过期时间,当内容key过期,但索引key中是没法设定过期的
当用户获取列表时,rediscache要对data进行处理(json_decode),同时,因为已过期的内容key不存在,通过sort命令获取的列表中存在false值,正常情况下是一个json结构化数据,
如果存在false值,触发转存动作,对索引key进行同样的sort,但不传get参数,得到ID号索引数据,从而对比得到需要删除的ID号,先删除正在进行中区域的索引数据
同时触发add动作,由rediscache再次存储数据,会自动根据源数据来进行入缓存作用
未开始数据转存正在进行中原理与正在进行的数据转存到已结束中
未开始的数据,添加时存入未开始内容key和未开始排序Key中,同时给未开始内容Key设定过期时间,也就是什么时候开始!
使用sort获取未开始列表的方法,因为未开始索引里的ID号是不会过期的,但内容有过期时间,所以一对比就知道哪个ID的数据由未开始转入已开始
在未开始索引key中删除,同时再次触发添加数据,由add方法自动判断数据存入的区域
支持多条件(AND)
因为每个条件都有一个索引key
分析多条件,得到多个索引key
使用sinterstore命令把多个索引key做交集并存入一个临时key中
使用这个临时索引key取列表数据命令原型
sinterstore key key1 key2 key3
缓存数据的重建
因为在rediscache中触发更新比较频繁,所以有可能会出现缓存数据与源数据不一致的情况
所以在管理后台做了缓存的重建功能
有待优化注意事项
数据重建时会自动加锁,防止多个操作,同时rediscache中这个表的缓存失效,自动从回调中的源数据中取数据
转存功能目前是基于用户触发,以后可以做异步,减少中间过程,优化用户获取列表的速度
因为rediscache做主动缓存内存代价太高,同时为了更高的性能,所以希望在缓存系统中存在的数据都是有效数据,尽量把该下架的下架,该删除的删除 (下架和删除,数据都会在rediscache中清除)
Redis做持久化,避免redis挂掉的情况下,需要对全部的数据做重建
空杯求学!!
原文地址:, 感谢原作者分享。
您可能感兴趣的代码博客分类:
Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载. 它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度.
Memcached基于一个存储键/值对的hashmap。
Redis是一个key-value存储系统,和Memcached类似。但是它支持存储的value类型相对更多,包括string(字符串)、 list(链表)、set(集合)、zset(sorted set --有序集合)和hashs(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都 是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期 性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis是一个高性能的key-value数据库。redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Python,Ruby,Erlang,PHP客户端,使用很方便.
下面主要介绍一下Redis与Memcached的不同。   1.网络IO模型
Memcached是多线程,非阻塞IO复用的网络模型,分为监听主线程和worker子线程,监听线程监听网络连接,接受请求后,将连接描述字pipe 传递给worker线程,进行读写IO, 网络层使用libevent封装的事件库,多线程模型可以发挥多核作用,但是引入了cache coherency和锁的问题,比如,Memcached最常用的stats 命令,实际Memcached所有操作都要对这个全局变量加锁,进行计数等工作,带来了性能损耗。
Redis使用单线程的IO复用模型,自己封装了一个简单的AeEvent事件处理框架,主要实现了epoll、kqueue和select,对于单纯只 有IO操作来说,单线程可以将速度优势发挥到最大,但是Redis也提供了一些简单的计算功能,比如排序、聚合等,对于这些操作,单线程模型实际会严重影 响整体吞吐量,CPU计算过程中,整个IO调度都是被阻塞住的。
  2.内存管理方面
Memcached使用预分配的内存池的方式,使用slab和大小不同的chunk来管理内存,Item根据大小选择合适的chunk存储,内存池的方式可以省去申请/释放内存的开销,并且能 减小内存碎片产生,但这种方式也会带来一定程度上的空间浪费,并且在内存仍然有很大空间时,新的数据也可能会被剔除,原因可以参考Timyang的文 章:http://timyang.net/data/Memcached-lru-evictions/
Redis使用现场申请内存的方式来存储数据,并且很少使用free-list等方式来优化内存分配,会在一定程度上存在内存碎片,Redis跟据存储命 令参数,会把带过期时间的数据单独存放在一起,并把它们称为临时数据,非临时数据是永远不会被剔除的,即便物理内存不够,导致swap也不会剔除任何非临 时数据(但会尝试剔除部分临时数据),这点上Redis更适合作为存储而不是cache。
  3.数据一致性问题
Memcached提供了cas命令,可以保证多个并发访问操作同一份数据的一致性问题。 Redis没有提供cas 命令,并不能保证这点,不过Redis提供了事务的功能,可以保证一串 命令的原子性,中间不会被任何操作打断。
  4.存储方式及其它方面
Memcached基本只支持简单的key-value存储,不支持枚举,不支持持久化和复制等功能
Redis除key/value之外,还支持list,set,sorted set,hash等众多数据结构,提供了KEYS
  进行枚举操作,但不能在线上使用,如果需要枚举线上数据,Redis提供了工具可以直接扫描其dump文件,枚举出所有数据,Redis还同时提供了持久化和复制等功能。
  5.关于不同语言的客户端支持
  在不同语言的客户端方面,Memcached和Redis都有丰富的第三方客户端可供选择,不过因为Memcached发展的时间更久一些,目前看在 客户端支持方面,Memcached的很多客户端更加成熟稳定,而Redis由于其协议本身就比Memcached复杂,加上作者不断增加新的功能等,对 应第三方客户端跟进速度可能会赶不上,有时可能需要自己在第三方客户端基础上做些修改才能更好的使用。
  根据以上比较不难看出,当我们不希望数据被踢出,或者需要除key/value之外的更多数据类型时,或者需要落地功能时,使用Redis比使用Memcached更合适。
  关于Redis的一些周边功能
Redis除了作为存储之外还提供了一些其它方面的功能,比如聚合计算、pubsub、scripting等,对于此类功能需要了解其实现原理,清楚地了解到它的局限 性后,才能正确的使用,比如pubsub功能,这个实际是没有任何持久化支持的,消费方连接闪断或重连之间过来的消息是会全部丢失的,又比如聚合计算和 scripting等功能受Redis单线程模型所限,是不可能达到很高的吞吐量的,需要谨慎使用。
  总的来说Redis作者是一位非常勤奋的开发者,可以经常看到作者在尝试着各种不同的新鲜想法和思路,针对这些方面的功能就要求我们需要深入了解后再使用。
  总结:
  1.Redis使用最佳方式是全部数据in-memory。
  2.Redis更多场景是作为Memcached的替代者来使用。
  3.当需要除key/value之外的更多数据类型支持时,使用Redis更合适。
  4.当存储的数据不能被剔除时,使用Redis更合适。
浏览 16200
浏览: 133919 次
来自: 杭州
我也遇到这样的问题,好奇葩,
总结的很是不错,学习了!
很抱歉,该链接已经失效了,多谢提点。
http://e-docs.bea.com/wls/docs7 ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'有没有方法让redis 自动做热数据缓存?
18:36:09 +08:00 · 9845 次点击
ORM将某些常用的数据从SQL加载在redis上,然后获取的时候有统一的方式,redis里面有的就用redis里面的,没有的去数据库找。再比如说弄个计数器,发现一个时间段对某个数据访问比较频繁就自动放到redis里面,之后冷了以后就删掉。
10 回复 &| &直到
20:21:08 +08:00
& & 18:42:42 +08:00
redis貌似可以设置expiration的吧,存的时候设置个过期时间就好了
& & 15:04:00 +08:00
个人想法,仅供参考啊
1.规划缓存。 就是那些东西需要放在缓存中。这个在开发初期 其实你应该就需要想明白,用计数器的方式也是一种方式。
如果(频繁访问) db要是能抗住,那么其实cache 紧紧是为了提升性能。
2.数据监控分析那些请求比较频繁,着重优化。
3.缓存预热功能。在高并发访问时候,加入1万请求,同时压到db可能崩溃,那么在应用启动前对 缓存预加载内容也是一种措施。
4.其实访问不频繁的也需要cache的,不过要是变化不大的 ,cache 超时时间设长点。
& & 15:05:35 +08:00
ps 我说的可能只适合网站应用奥。在通俗点 就是 cache命中率的问题。
& & 17:36:13 +08:00
楼上的和我用一样的头像
& & 01:01:53 +08:00
你是左撇子
& & 14:41:04 +08:00
这类系统可以用 Redis 的 EXPIRE 命令来实现。
EXPIRE 命令的行为是:
1)在 key 没有设置生存时间时,那么设置 key 的生存时间;
2)如果 key 已经设置了生存时间,那么 EXPIRE 就会更新这个 key 的生存时间(注意更新的方式是覆盖而不是延长)。
根据这一特性,可以在写入时设置数据 key 的生存时间,在读取时更新数据 key 的生存时间:这样在给定时间内被频繁访问的数据就可以一直保存下去,而没人访问的数据就会因为过期而被自动删除。
以一个字符串 key 为例子:
def cached_set(key, value)
$redis.set(key, value)
$redis.expire(key, 5 * 60)
end
def cached_get(key)
$redis.get(key)
$redis.expire(key, 5 * 60)
end
以上的代码只会保存 key 数据 5 分钟,如果 5 分钟之内有人访问这个 key ,那么 key 的生存时间就会重新设为 5 分钟,只要一直有人访问,就会一直“续期”下去。
至于没人访问的数据,在 5 分钟到期之后,就会自动被删除了。
这应该就能达到缓存热数据的目的了。
最后,使用这种技术时,要记得在更新数据之后刷新缓存,否则会出现缓存过期的现象。
& & 14:44:18 +08:00
Tips:将 set/get 命令和 expire 命令包裹在一条事务中,效果更佳。嗯。
& & 23:36:56 +08:00
@ set 和 expire 命令可以合并:setex
& & 07:47:13 +08:00
@ 是的,感谢补充。
& & 20:21:08 +08:00
我就是觉得麻烦,每次 get 的时候也要设置过期。很麻烦。
& · & 440 人在线 & 最高记录 3541 & · &
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.0 · 66ms · UTC 23:00 · PVG 07:00 · LAX 15:00 · JFK 18:00? Do have faith in what you're doing.博客分类:
1. 生存时间
1.1 命令介绍
在实际的开发中经常会遇到一些有时效的数据,比如限时优惠活动、缓存或验证码等,过了一定的时间就需要删除这些数据。在关系数据库中一般需要额外的一个字段记录到期时间,然后定期检测删除过期数据。而在Redis中可以使用EXPIRE命令设置一个键的生存时间,到时间后Redis会自动删除它。
EXPIRE命令的使用方法为:
EXPIRE key seconds
其中seconds参数表示键的生存时间,单位是秒。如要想让session:29e3d键在15分钟后被删除:
redis>SET session:29e3d uid1314
redis>EXPIRE session:29e3d 900
(integer) 1
EXPIRE命令返回1表示设置成功,返回0则表示键不存在或设置失败。例如:
redis>DEL session:29e3d
(integer) 1
redis>EXPIRE session:29e3d 900
(integer) 0
如果想知道一个键还有多久的时间会被删除,可以使用TTL命令。返回值是键的剩余时间
(单位是秒):
redis>SET foo bar
redis>EXPIRE foo 20
(integer) 1
redis>TTL foo
(integer) 15
redis>TTL foo
(integer) 7
redis> TTL foo
(integer) -2
可见随着时间的不同,foo键的生存时间逐渐减少,20秒后foo键会被删除。当键不存在时TTL命令会返回-2。另外没有为键设置生存时间(即永久存在,这是建立一个键后的默认情况)使用TTL会返回-1:
redis>SET persistKey value
redis>TTL persistKey
(integer) -1
注意:
在 Redis 2.8 以前,当 key 不存在,或者 key 没有设置剩余生存时间时,命令都返回 -1 。
如果想取消键的生存时间设置(即将键恢复成永久的),可以使用PERSIST命令。如果生存时间被成功清除则返回1;否则返回0(因为键不存在或键本来就是永久的):
redis>SET foo bar
redis>EXPIRE foo 20
(integer) 1
redis>PERSIST foo
(integer) 1
redis>TTL foo
(integer) -1
(1)除了PERSIST命令之外,(2)使用SET或GETSET命令为键赋值也会同时清除键的生存时间,例如:
redis>EXPIRE foo 20
(integer) 1
redis>SET foo bar
redis>TTL foo
(integer) -1
补充:
getset命令:
GETSET key value
将给定key的值设为value,并返回key的旧值。
当key存在但不是字符串类型时,返回一个错误。
时间复杂度:O(1)
返回值:返回给定key的旧值(old value)。
当key没有旧值时,返回nil。
redis& EXISTS mail
(integer) 0
redis& GETSET mail
# 因为mail之前不存在,没有旧值,返回nil
redis& GETSET mail
# mail被更新,旧值被返回
使用EXPIRE命令会重新设置键的生存时间,就像这样:
redis>SET foo bar
redis>EXPIRE foo 20
(integer) 1
redis>TTL foo
(integer) 15
redis>EXPIRE foo 20
(integer) 1
redis>TTL foo
(integer) 17
其他只对键值进行操作的命令(如INCR、LPUSH、HSET、ZREM)均不会影响键的生存时间。
EXPIRE命令的seconds参数必须是整数,所以最小单位是1秒。如果想要更精确的控制键的生存时间应该使用PEXPIRE命令,PEXPIRE命令与EXPIRE的唯一区别是前者的时间单位是毫秒,即PEXPIRE key 1000与EXPIRE key 1等价。对应地可以用PTTL命令以毫秒为单位返回键的剩余时间。
注意: 如果使用WATCH命令监测了一个拥有生存时间的键,该键时间到期自动删除并不会被WATCH命令认为该键被改变。
另外还有两个相对不太常用的命令:EXPIREAT 和PEXPIREAT。
EXPIREAT命令与EXPIRE命令的差别在于前者使用Unix时间作为第二个参数表示键的生存时间的截止时间。PEXPIREAT命令与EXPIREAT命令的区别是前者的时间单位是毫秒。例如:
redis>SET foo bar
redis>EXPIREAT foo
(integer) 1
redis>TTL foo
(integer) 142
redis>PEXPIREAT foo 0
(integer) 1
1.2 实现缓存
为了提高网站的负载能力,常常需要将一些访问频率较高但是对CPU或IO资源消耗较大的操作的结果缓存起来,并希望让这些缓存过一段时间自动过期。比如教务网站要对全校所有学生的各个科目的成绩汇总排名,并在首页上显示前10名的学生姓名,由于计算过程较耗资源,所以可以将结果使用一个Redis的字符串键缓存起来。由于学生成绩总在不断地变化,需要每隔两个小时就重新计算一次排名,这可以通过给键设置生存时间的方式实现。每次用户访问首页时程序先查询缓存键是否存在,如果存在则直接使用缓存的值;否则重新计算排名并将计算结果赋值给该键并同时设置该键的生存时间为两个小时。伪代码如下:
rank=GET cache:rank
if not rank
rank=计算排名...
SET cache:rank, rank
EXPIRE cache:rank, 7200
EXEC
然而在一些场合中这种方法并不能满足需要。当服务器内存有限时,如果大量地使用缓存键且生存时间设置得过长就会导致Redis占满内存;另一方面如果为了防止Redis占用内存过大而将缓存键的生存时间设得太短,就可能导致缓存命中率过低并且大量内存白白地闲置。实际开发中会发现很难为缓存键设置合理的生存时间,为此可以限制Redis能够使用的最大内存,并让Redis按照一定的规则淘汰不需要的缓存键,这种方式在只将Redis用作缓存系统时非常实用。
具体的设置方法为:
修改配置文件的maxmemory参数,限制Redis最大可用内存大小(单位是字节),当超出了这个限制时Redis会依据maxmemory-policy参数指定的策略来删除不需要的键,直到Redis占用的内存小于指定内存。
maxmemory-policy支持的规则如表4-1所示。其中的LRU(Least Recently Used)算法即“最近最少使用”,其认为最近最少使用的键在未来一段时间内也不会被用到,即当需要空间时这些键是可以被删除的。
如当maxmemory-policy设置为allkeys-lru时,一旦Redis占用的内存超过了限制值,Redis会不断地删除数据库中最近最少使用的键① ,直到占用的内存小于限制值。
注释:
①事实上Redis并不会准确地将整个数据库中最久未被使用的键删除,而是每次从数据库中随机取3个键并删除这3个键中最久未被使用的键。删除生存时间最接近的键的实现方法也是这样。“3”这个数字可以通过Redis的配置文件中的maxmemory-samples参数设置。
浏览: 220870 次
来自: OnePiece
谢谢分享,很清楚的讲明了原理。
难得的笔记
mini188 写道用MD5来解决碰撞是不是也是可行的呢?个人 ...
用MD5来解决碰撞是不是也是可行的呢?
写的不错~~ July大神貌似写过所有海量数据的万金油解法是先 ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'}

我要回帖

更多关于 redis缓存怎么使用 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信