聊聊Elasticsearch的SingleObjectCache

本文深入解析了Elasticsearch中SingleObjectCache类的工作原理,包括其构造器、getOrRefresh方法及如何通过判断缓存值是否过期来刷新值。通过FsService类实例,展示了SingleObjectCache在实际场景中的应用。

本文主要研究一下Elasticsearch的SingleObjectCache

SingleObjectCache

elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/common/util/SingleObjectCache.java

public abstract class SingleObjectCache<T>{

    private volatile T cached;
    private Lock refreshLock = new ReentrantLock();
    private final TimeValue refreshInterval;
    protected long lastRefreshTimestamp = 0;

    protected SingleObjectCache(TimeValue refreshInterval, T initialValue) {
        if (initialValue == null) {
            throw new IllegalArgumentException("initialValue must not be null");
        }
        this.refreshInterval = refreshInterval;
        cached = initialValue;
    }


    /**
     * Returns the currently cached object and potentially refreshes the cache before returning.
     */
    public T getOrRefresh() {
        if (needsRefresh()) {
            if(refreshLock.tryLock()) {
                try {
                    if (needsRefresh()) { // check again!
                        cached = refresh();
                        assert cached != null;
                        lastRefreshTimestamp = System.currentTimeMillis();
                    }
                } finally {
                    refreshLock.unlock();
                }
            }
        }
        assert cached != null;
        return cached;
    }

    /** Return the potentially stale cached entry. */
    protected final T getNoRefresh() {
        return cached;
    }

    /**
     * Returns a new instance to cache
     */
    protected abstract T refresh();

    /**
     * Returns <code>true</code> iff the cache needs to be refreshed.
     */
    protected boolean needsRefresh() {
        if (refreshInterval.millis() == 0) {
            return true;
        }
        final long currentTime = System.currentTimeMillis();
        return (currentTime - lastRefreshTimestamp) > refreshInterval.millis();
    }
}
  • SingleObjectCache的构造器要求refreshInterval、initialValue两个参数;它提供了getOrRefresh方法,该方法会判断该cached值是否过期,如果过期则调用refresh方法刷新值,同时更新lastRefreshTimestamp,如果没过期则返回cached值

实例

elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/monitor/fs/FsService.java

public class FsService {

    private static final Logger logger = LogManager.getLogger(FsService.class);

    private final FsProbe probe;
    private final TimeValue refreshInterval;
    private final SingleObjectCache<FsInfo> cache;
    private final ClusterInfoService clusterInfoService;

    public static final Setting<TimeValue> REFRESH_INTERVAL_SETTING =
        Setting.timeSetting(
            "monitor.fs.refresh_interval",
            TimeValue.timeValueSeconds(1),
            TimeValue.timeValueSeconds(1),
            Property.NodeScope);

    public FsService(final Settings settings, final NodeEnvironment nodeEnvironment, ClusterInfoService clusterInfoService) {
        this.probe = new FsProbe(nodeEnvironment);
        this.clusterInfoService = clusterInfoService;
        refreshInterval = REFRESH_INTERVAL_SETTING.get(settings);
        logger.debug("using refresh_interval [{}]", refreshInterval);
        cache = new FsInfoCache(refreshInterval, stats(probe, null, logger, null));
    }

    public FsInfo stats() {
        return cache.getOrRefresh();
    }

    private static FsInfo stats(FsProbe probe, FsInfo initialValue, Logger logger, @Nullable ClusterInfo clusterInfo) {
        try {
            return probe.stats(initialValue, clusterInfo);
        } catch (IOException e) {
            logger.debug("unexpected exception reading filesystem info", e);
            return null;
        }
    }

    private class FsInfoCache extends SingleObjectCache<FsInfo> {

        private final FsInfo initialValue;

        FsInfoCache(TimeValue interval, FsInfo initialValue) {
            super(interval, initialValue);
            this.initialValue = initialValue;
        }

        @Override
        protected FsInfo refresh() {
            return stats(probe, initialValue, logger, clusterInfoService.getClusterInfo());
        }

    }

}
  • FsService的构造器使用FsInfoCache创建了cache,其无参的stats方法执行的是cache.getOrRefresh();FsInfoCache继承了SingleObjectCache,它的refresh方法调用的是stats方法,该方法通过probe.stats(initialValue, clusterInfo)来刷新值

小结

SingleObjectCache的构造器要求refreshInterval、initialValue两个参数;它提供了getOrRefresh方法,该方法会判断该cached值是否过期,如果过期则调用refresh方法刷新值,同时更新lastRefreshTimestamp,如果没过期则返回cached值

doc

转载于:https://my.oschina.net/go4it/blog/3059908

《狂神聊Elasticsearch.md》是一篇关于Elasticsearch的文章。Elasticsearch是一个开源的分布式搜索和分析引擎,它被广泛应用于全文搜索、数据分析、日志处理等场景。这篇文章详细介绍了Elasticsearch的原理、基本操作和常用功能。 文章首先介绍了Elasticsearch的基本概念和架构。它采用分布式的倒排索引,以实现高效的全文搜索。集群中的每个节点都可以承担不同的角色,包括主节点、数据节点和协调节点。这种设计使得Elasticsearch具有高可用性和弹性伸缩性。 接下来,文章详细介绍了如何安装和配置Elasticsearch。它提供了两种安装方式,一种是通过官方下载安装包进行安装,另一种是通过Docker容器进行安装。然后,文章介绍了如何配置Elasticsearch的参数,包括网络配置、集群配置和节点配置等。 文章还介绍了Elasticsearch的常用功能,包括索引管理、数据查询、聚合分析和文档更新等。通过示例代码和详细讲解,读者可以了解到如何创建索引、添加文档、执行查询和聚合操作。文章还介绍了如何使用Kibana进行数据可视化和监控。 最后,文章提到了Elasticsearch的一些高级功能,包括分布式搜索、索引优化和集群监控等。它介绍了如何通过查询路由和复制机制实现分布式搜索,并讲解了如何通过分片和副本优化索引的性能和可靠性。此外,文章还介绍了如何使用Elasticsearch的API和插件进行集群监控和故障诊断。 总之,这篇文章全面而详细地介绍了Elasticsearch的原理、操作和常用功能,对于想要学习和使用Elasticsearch的人来说,是一篇非常有价值的参考资料。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值