分布式追踪系统
随着微服务和云原生开发的兴起,越来越多应用基于分布式进行开发,大型应用拆分为微服务后,服务之间的依赖和调用变得越来越复杂。微服务提供了一个强大的体系结构,但也有面临了一些挑战,例如:
- 如何调试和观察跨复杂网络的分布式调用?
- 如何分析服务链路的瓶颈并对其进行调优?
- 如何快速进行服务链路的故障发现?
- ……
为了更好地维护这些服务,软件领域出现了 Observability 思想。
随着微服务和云原生开发的兴起,越来越多应用基于分布式进行开发,大型应用拆分为微服务后,服务之间的依赖和调用变得越来越复杂。微服务提供了一个强大的体系结构,但也有面临了一些挑战,例如:
为了更好地维护这些服务,软件领域出现了 Observability 思想。
本篇是论文Dapper,大规模分布式系统的跟踪系统的中文简单翻译
Calcite 支持管理底层数据库的元数据信息和根据元数据优化查询 SQL。但是 Calcite 不直接存储底层系统中的元数据信息,用户需要先将元数据注册到 Calcite Catalog 中,才可以使用Calcite提供的能力。
Apache Calcite是一个动态的数据管理框架,从功能上看它有很多数据库管理系统的典型功能,比如 SQL 解析、SQL 校验、SQL 查询优化、SQL 生成、数据连接查询等等,但省略了一些关键功能:数据存储,处理数据的算法以及用于存储元数据的存储库。从另一方面看,正因为 Calcite 这种与数据处理和存储的无关的设计,才使它成为在多个数据源和数据处理引擎之间进行协调的绝佳选择。它也是构建数据库的完美基础:只需添加数据即可。
Calcite 的主要功能是 SQL 语法解析(parse)和优化(optimazation)。首先它会把 SQL 语句解析成抽象语法树(AST Abstract Syntax Tree),并基于一定规则或成本对 AST 的算法与关系进行优化,最后推给各个数据处理引擎进行执行。
一般来说 Calcite 解析 SQL 有下面几步:

Flink是使用 JVM 的大数据开源计算框架,基于 JVM 的数据分析引擎都需要面对将大量数据存到内存中,这就不得不面对 JVM 存在的几个问题:
对于第一个问题,如果采用基类存储就可以解决。而第二个问题,可以考虑是使用直接内存和内存池来解决 Full GC 的问题。OOM 问题需要支持内存数据溢写到磁盘,即支持内存数据的序列化和反序列化。这里不使用 JDK 原始 buffer 的原因是 JDK Buffer只支持存储相同固定类型的实例数据,而实际上流式数据处理的总是一行数据,且数据要支持可扩展的类系统。
因此,Flink 选择了实现自己管理的内存单元和可扩展的类型系统,也就是接下来介绍的 Buffer框架(Memory Segment) 和对应的 TypeSerializer。

这一个常在元旦附近出没的Bug,主要原因是Java 日期格式FormatString 中的yyyy 被写成了YYYY。 要注意的是,对于年份来说,大写的Y和小写的y其意义是不同的。y 是Year, Y 表示的是Week year
循环冗余校验(英语:Cyclic redundancy check,通称“CRC”)是一种根据网络数据包或电脑文件等数据产生简短固定位数校验码的一种散列函数,主要用来检测或校验数据传输或者保存后可能出现的错误。生成的数字在传输或者存储之前计算出来并且附加到数据后面,然后接收方进行检验确定数据是否发生变化1。
最近遇到一个问题,在执行长事务任务的过程中,频繁出现异常 com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Communications link failure during commit(). Transaction resolution unknown.即,事务提交时发现连接已经失效。一开始以为是连接超时设置的有问题,但是这个异常重复出现,并且,数据库连接池设置了testOnBorrow。所以应该不是连接超时导致。后来发现,出现报错时,事务开启都刚好超过了5S。
经过和RDS同学的沟通。他们设置了kill_idle_transaction 这个参数,并且默认为5S
在线上遇到5.7.26的锁问题,需要解决idle事务长时间挂起的问题。同时也调研了现有的mysql timeout机制,以确保其和现有的timeout机制可以吻合。Percona从5.1.59-13.0引入了innodb_kill_idle_transaction,用于解决长事务场景,即对idle事务设定一个超时时间,对超过该时间的事务所在的用户连接进行断开。
最近在线上环境遇到一个问题,nacos客户端线程池中有96个线程在等待.一开始以为是哪里配置有误,于是检查了nacos的配置。没有发现问题。于是只能看nacos源码了.
public ClientWorker(final HttpAgent agent, final ConfigFilterChainManager configFilterChainManager, final Properties properties) {
this.agent = agent;
this.configFilterChainManager = configFilterChainManager;
// Initialize the timeout parameter
init(properties);
executor = Executors.newScheduledThreadPool(1, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.Worker." + agent.getName());
t.setDaemon(true);
return t;
}
});
executorService = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("com.alibaba.nacos.client.Worker.longPolling." + agent.getName());
t.setDaemon(true);
return t;
}
});
executor.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
try {
checkConfigInfo();
} catch (Throwable e) {
LOGGER.error("[" + agent.getName() + "] [sub-check] rotate check error", e);
}
}
}, 1L, 10L, TimeUnit.MILLISECONDS);
}如上面的代码,nacos长轮询线程池在初始化时使用了Runtime.getRuntime().availableProcessors().而宿主机恰好是48核*2。因此判断JVM获取可用核数错误,拿到的是宿主机核数而非容器可用核数1。
在前面的编译原理-词法分析一文中,我们介绍了基于正则表达式方式构建NFA和DFA进行词法分析的方案。本文将基于该方案,扩展一些功能,实现一个正则表达式执行引擎JRegex - alpha版本。