我们经常会碰到具有生命周期的数据,比如key/value对子,很多人都使用线程扫描的方式。这种做法虽然简单,但是并不高效。因为每清理一次数据都要加锁,这会影响正常的数据读写性能。
      storm实现了一种非常高效的map,它采用的算法可以在expirationSecs到expirationSecs * (1 + 1 / (numBuckets-1))时间内将过期数据删除,而删除一批过期数据只要加1次锁。
 
    接下来让我们看看它的实现原理:
 
    TimeCacheMap:

    

    TimeCacheMap使用了桶的数据结构,每个桶可以看成是1个hash map, 新数据全部会写到第1个桶,假设过期时间是100秒,那100秒之后第一个桶就应该被全部删掉,所以TimeCacheMap用了1个独立的清理线程每隔25秒(过期时间/(桶数-1))将最后一个桶全部清理,然后将前面的4个桶往后挪,新建一个桶作为第一个桶,而新来的数据总是写到第一个桶。这样,所有的数据都会在125秒之后被清理掉。因为清理是以桶为单位的,所以清理的效率非常高,只需要加1次锁。
    实际上,这些所谓“过期”的数据并不一定是要删除,而是做一些其他的处理,因此TimeCacheMap还提供了回调的接口,用户可以自己决定怎么处理“过期”的数据。
    其实采用桶的方式提升并发性能的例子很多,但中心思想都是减小锁的粒度。在storm系统里面,spout生成的消息全部保存在本地的TimeCacheMap里面,当消息处理超时,这些过期的消息会自动被清理线程处理掉。