【问题标题】:How to prevent Cache Breakdown by nonexistent id?如何防止不存在的 id 导致缓存崩溃?
【发布时间】:2013-07-01 22:37:57
【问题描述】:

如果有一个id不存在的请求,Cache不会得到它,请求会通过Database去查询。

不存在的id请求会全部命中数据库,如果这是攻击,缓存无法保护数据库。

数据库很快就会关闭。

那么我该怎么做才能防止这种类型的攻击呢?

附:数据库中的数据太多。而如果一个id只访问一次,Null Object Cache就不起作用了。

【问题讨论】:

    标签: java database caching architecture


    【解决方案1】:

    您可以缓存一个 Optional,如果响应为空,您将在第一个请求中保存 Optional.absent()。您必须在数据库中存在关联的 Id 时立即使该缓存的 Optional 实体无效,或者如果您在不断增长的缓存中遇到内存问题,则必须尽快使该实体无效。

    我喜欢 guava 的 Cache 和 Optional 类,因为我认为它们解决了大多数可能的问题,我将在我的示例中使用它们:

    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    
    import com.google.common.base.Optional;
    import com.google.common.cache.Cache;
    import com.google.common.cache.CacheBuilder;
    
    
    public class OptionalCacheUsage {
    
      private static final Cache<Id, Optional<Entity>> cache = CacheBuilder.newBuilder()
          .softValues()
          .expireAfterWrite(5, TimeUnit.MINUTES)
          .build();
    
      private static final Database db = Databases.getDatabase();
    
      Entity findEntity(final Id requestedId) throws ExecutionException, EntityNotFoundException {
        final Optional<Entity> optionalEntity = cache.get(requestedId, new Callable<Optional<Entity>>() {
    
          @Override public Optional<Entity> call() throws Exception {
            return Optional.fromNullable(db.getById(requestedId));
          }});
        if (optionalEntity.isPresent()) {
          return optionalEntity.get();
        } else {
          throw new EntityNotFoundException();
        }
      }
    
      Id saveEntity(final Entity newEntity) {
        final Id savedId = db.save(newEntity);
        cache.invalidate(savedId);
        return savedId;
      }
    }
    

    【讨论】:

    • 但是数据库的数据太多了。如果一个id只访问一次,这个解决方案就行不通了。
    • 是的,不会。我认为最好的方法是限制可能的 id,然后使用这个缓存。比如:我今天有 1000 个实体,所以我将可能的 id 限制在 0、2000 范围内。如果不咨询数据库,则超出范围的任何内容都被认为不存在,并且您会定期更新该范围的最大值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    • 2016-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多