算法之MD5
MD5 即Message-Digest Algorithm 5 (信息-摘要算法5)。MD5 使用little-endian(小端模式),输入任意不定长度信息,以 512-bit 进行分组,生成四个32-bit 数据,最后联合输出固定 128-bit 的信息摘要。
MD5 不是足够安全的。Hans Dobbertin在1996年找到了两个不同的512-bit 块,它们 在MD5 计算下产生相同的hash 值。至今还没有真正找到两个不同的消息,它们的MD5 的hash 值相等。
MD5 即Message-Digest Algorithm 5 (信息-摘要算法5)。MD5 使用little-endian(小端模式),输入任意不定长度信息,以 512-bit 进行分组,生成四个32-bit 数据,最后联合输出固定 128-bit 的信息摘要。
MD5 不是足够安全的。Hans Dobbertin在1996年找到了两个不同的512-bit 块,它们 在MD5 计算下产生相同的hash 值。至今还没有真正找到两个不同的消息,它们的MD5 的hash 值相等。
日志是服务中一个重要组成部分,当优化性能的时候,也要思考对日志的性能优化。
随着微服务和云原生开发的兴起,越来越多应用基于分布式进行开发,大型应用拆分为微服务后,服务之间的依赖和调用变得越来越复杂。微服务提供了一个强大的体系结构,但也有面临了一些挑战,例如:
为了更好地维护这些服务,软件领域出现了 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版本。
解析是编译器将一系列标记转换为树表示的过程:
Add
Parser / \
"1 + 2 * 3" -------> 1 Mul
/ \
2 3Pratt Parser解析是手写解析最常用的技术之一。
最近在maven打包的时候遇到一个问题:
Could not transfer artifact io.airlift:airbase:pom:128 from/to maven-default-http-blocker 使用的maven版本是 3.8.4. 原因是maven自3.8.1升级后需要https协议的仓库地址,见 Release Notes – Maven 3.8.1。
编译器模型:
graph LR 源代码-->|词法分析器|词法单元 词法单元-->|语法分析器|语法分析树 语法分析树-->|中间代码生成器|中间代码 中间代码-->|代码优化,机器无关|中间代码 中间代码-->|代码生成器|目标代码 目标代码-->|机器相关代码优化|机器码 机器码-->output((机器码执行))
MurmurHash 是一种非加密hash功能,适用于基于hash的一般查找。由Austin Appleby在2008年发明, 并出现了多个变种,目前托管在github。该名称来自两个基本操作,乘 multiply 和 旋转 rotate(该算法实际上使用shift和xor而不是rotate),用于其内循环。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。
Redis在实现字典时用到了两种不同的哈希算法,MurmurHash便是其中一种(另一种是djb),在Redis中应用十分广泛,包括数据库、集群、哈希键、阻塞操作等功能都用到了这个算法。该算法最新版本是MurmurHash3,基于MurmurHash2改进了一些小瑕疵,使得速度更快,实现了32位(低延时)、128位HashKey,尤其对大块的数据,具有较高的平衡性与低碰撞率。
很多 JVM CPU Profiler(例如VisualVM,NetBean Profiler,YourKit 和 JProfiler等)都提供了CPU分析器。一般CPU Profiling功能有两种实现方式: Sampling和Instrumentation。
Sampling由于低开销的特性,更适合用在CPU密集型的应用中,以及不可接受大量性能开销的线上服务中。而Instrumentation则更适合用在I/O密集的应用中、对性能开销不敏感以及确实需要精确统计的场景中。上面介绍的CPU Profiler更多的是基于Sampling来实现。
前面介绍过Java Buffer使用的内存分堆内内存(Heap)和堆外内存(No Heap),本文将介绍DirectBuffer的实现原理,以DirectByteBuffer为例1。