算法之CRC
循环冗余校验(英语:Cyclic redundancy check,通称“CRC”)是一种根据网络数据包或电脑文件等数据产生简短固定位数校验码的一种散列函数,主要用来检测或校验数据传输或者保存后可能出现的错误。生成的数字在传输或者存储之前计算出来并且附加到数据后面,然后接收方进行检验确定数据是否发生变化1。
循环冗余校验(英语: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。
Java 传统 IO 是面向流的,流的处理是单向「只能从输入流中读取数据,或是向输出流中写入数据」且阻塞的。通常都是从输入流中边读取数据边处理数据,这样 IO 处理效率就会很低,基于上述原因,JDK1.4 引入了 NIO,而 NIO 是面向 Buffer 的,在处理 IO 操作的时候,会一次性将 Channel 中的数据读取到 Buffer 中然后在做后续处理,向 Channel 中写入数据也是一样,也是需要一个 Buffer 做中转,然后将 Buffer 中的数据批量写入 Channel 中。通过增加Buffer支持了数据的灵活处理。
除此之外,Nio Buffer 还提供了堆外的直接内存和内存映射相关的访问方式,来避免内存之间的来回拷贝,所以即使在传统 IO 中用到了 BufferedInputStream 也还是没办法和 Nio Buffer 相匹敌。本文将结合源码介绍 ByteBuffer^[本文JDK源码基于Java8]。
在之前介绍linux命令free时,有提到过docker中使用free命令获得的常常是宿主机的内存使用情况。那么怎么获取docker中内存的使用情况呢?
在不同领域中深耕的组织都在不约而同地尝试发现相似的软件构建模式。 希望这些系统会更健壮、更具回弹性 、更灵活,也能更好地满足现代化的需求。
近年来,应用程序的需求已经发生了戏剧性的更改,模式变化也随之而来。仅在几年前, 一个大型应用程序通常拥有数十台服务器、 秒级的响应时间、 数小时的维护时间以及GB级的数据。 而今,应用程序被部署到了形态各异的载体上, 从移动设备到运行着数以千计的多核心处理器的云端集群。 用户期望着毫秒级的响应时间,以及服务100%正常运行(随时可用)。 而数据则以PB计量。 昨日的软件架构已经根本无法满足今天的需求。
我们相信大家需要一套贯通整个系统的架构设计方案, 而设计中必需要关注的各个角度也已被理清, 我们需要系统具备以下特质:即时响应性(Responsive)、回弹性(Resilient)、弹性(Elastic)以及消息驱动(Message Driven)。 我们称这样的系统为反应式系统(Reactive System)。
版本 2.0,2014 年 9 月 16 日发布
在《UNIX网络编程》中介绍了5种I/O模型:阻塞I/O、非阻塞I/O、I/O复用、SIGIO、异步I/O; Unix的I/O模型,一个输入操作通常包括两个不同的阶段:
对于一个套接字的输入操作,第一步通常涉及等待数据从网络到达,当所等待分组到达时,被复制到内核的某个缓冲区;第二步把数据从内核缓冲区复制到应用进程缓冲区。
网络应用需要处理的无非就是两大类问题,网络IO,数据计算。相对于后者,网络IO的延迟,给应用带来的性能瓶颈大于后者。网络IO的模型大致有如下几种:
RAID ( Redundant Array of Independent Disks )即独立磁盘冗余阵列,通常简称为磁盘阵列。简单地说, RAID 是由多个独立的高性能磁盘驱动器组成的磁盘子系统,从而提供比单个磁盘更高的存储性能和数据冗余的技术。
先介绍下系统的IO原型架构。CPU 通过内存总线(memory bus)连接到系统内存。显卡或者其他高性能 I/O 设备通过常规的I/O 总线(I/O bus)连接到系统,在许多现代系统中会是 PCI 或它的衍生形式。最后,更下面是外围总线(peripheral bus),比如 SCSI、SATA 或者 USB。它们将最慢的设备连接到系统,包括磁盘、鼠标及其他类似设备。

考虑物理布局及造价成本。越快的I/O 设备的总线越短,因此高性能的内存总线没有足够的空间连接太多设备。另外,在工程上高性能总线的造价非常高。所以,系统的设计采用了这种分层的方式,这样可以让要求高性能的设 备(比如显卡)离 CPU 更近一些,低性能的设备离 CPU 远一些。将磁盘和其他低速设备连到外围总线的好处很多,其中较为突出的好处就是你可以在外围总线上连接大量的设备。
本文翻译自 What Every Programmer Should Know About Memory的第4,5章