Redis是一个伟大的工具,用来在内存中存储列表是很合适的。
不过,如果你想要快速搜索列表,同时需要让列表中每项都在一定时间后过期,应该怎么做呢?
首先,当然不能使用不同的类似的key存储数据,然后使用keys
命令来获取所有类似key的数据。这样的开销是不可接受的。
Redis并没有直接提供方法做这件事,但是这是可以做到的!虽然最后用的未必是Redis的List数据结构。
问题:
我想在cmdb数据采集中,为API 这里加上一个认证的功能,毕竟不能谁都可以随便提交数据给我, 我就接收的所以还是需要一个认证的。
参考了 tornado 中的一个验证方式。
1. 服务端 于 客户端共同维护同一个key。 客户端在发送数据过来时要携带token。 这个token 由这个key + 客户端的当前时间,MD5加密之后的字符串, 和 客户端的当前时间的时间戳组成。
2. 服务端 除了维护key意外,另外维护一个 过期时间。 比如是10秒钟。 当客户端token过来后。
1)取出token中的 客户端的时间戳,减去过期时间10秒, 于服务器端的当前时间做对比。 如果客户端的这个时间 比服务端当前时间减去10秒后,还要小的话。 那就说明这个时间太久远了直接不准链接。
2)拿着客户端的时间戳 和自己维护的key, 同样的加密后。 判断一下这个加密后的值是否已经访问过了。(就是用redis解决这个). 如果访问过了就不准再访问
3)最后比对一下, 服务端和客户端的加密值是否一样, 一样就通过。 并且把这个加密后的值,再加到redis中。
然后我在网上找到这篇文章,它描述了两种办法。
Redis的集合:“无序的字符串集合”,它的项有下面的特点
- 唯一的(如果加入重复的数据,redis会默默的拒绝)
- 无序,并且不可以用任何方法(在redis中)排序
Redis有序集合:“有序的字符串集合“,它的项有下面的特点:
- 和集合一样,每个项都是唯一的
- 拥有积分(项的积分并不必须是唯一的)
- 根据积分排序(有索引)
两种解决方法:
1. 有序集合
查询有序集合是非常快的,因为redis将一个列表转换成了集合,所以当我们访问它的时候,它已经是排好序的了。
根据Redis文档的描述:
“排序集是通过一个双端口数据结构实现的,其中包含一个跳跃列表和一个哈希表,所以每次我们添加一个元素Redis都会执行一个O(log(N))操作。这很好,但当我们要求排序后的元素时Redis根本不需要做任何工作,它已经排好序了“
当然,你不可以对有序集合中每个项设置过期时间。
你可以通过score
对有序集合进行查询,我们可以利用这个地方来形成一个解决方案: (其中scroe指的就是该有序集合成员的次序。默认从小到大。)
对于加入到有序集合的每个项,我们都将它的score设置为 Unix Timestamp,这个timestamp代表它的过期时间。然后,我们加入一个定时任务,定时移除那些过期的数据。
2. 多个集合以及过期时间
这个方案使用普通的集合。
因为不能对集合中每项都设置TTL,但是可以对整个集合设置TTL。所以,我们可以将每个时间段的数据放在一个集合中。然后对这个集合设置过期时间。