I/O,一直以来都是操作系统中核心中的核心,从我们进入互联网时代以后,全世界的互联网用户爆发式地增长,一批又一批的提供互联网服务的大型跨国公司不断地崛起,它们承载了全世界百亿、千亿量级的网络流量,I/O 密集型的系统如网络服务器、数据库等逐渐占据了服务端领域,在海量的互联网用户面前,服务端的技术挑战不断涌现,网络服务器和数据库等系统的性能瓶颈愈发明显,而且大多数瓶颈都落在了 I/O 头上。Linux 作为有史以来应用最广泛的服务端操作系统,而且相较于 Windows、Solaris 等闭源操作系统,Linux 开放了其内核的全部源代码,这三十余年以来,全世界有无数的开发者参与其中,对 Linux 内核进行优化和修复,因此 Linux 的底层 I/O 技术发展史基本就等同于人类与计算机 I/O 的抗争史。
本文将分为两大部分,第一部分会深入浅出地剖析整个 Linux I/O 栈,带领读者从用户空间出发,进入内核空间,直达底层物理硬件,让读者能深刻地理解整个 Linux I/O 栈的层次结构、底层实现以及历史发展;第二部分则是基于第一部分的知识,揭示了 Linux 是如何在传统 I/O 模式中走出来并且万丈高楼平地起,直至手摘星辰,对 I/O 进行深度的改造从而实现 Zero-copy I/O,这部分内容会全方位地揭秘 Zero-copy (零拷贝) 这项技术,以及它是如何在 Linux I/O 栈上大放异彩,并成为绝大部分服务端高性能 I/O 的基石。
相对于 UDP 这样的无连接 (connection-less) 协议,TCP 是一种连接导向 (connection-oriented) 的可靠性协议,其目标是在不可靠的网络环境中实现可靠的数据传输。我们知道网络环境是复杂多变的,网络通信本质上是一种不可靠通信,要在不可靠的网络中实现 TCP 这样的可靠通信协议需要做很多工作:基于 TCP 协议的双端通信,在数据传输前需要建立一条连接,然后基于该连接来进行可靠的通信;在传输数据的过程中还要利用校验和、序列号、确认应答 (ACK)、重发控制、连接管理以及流量窗口控制等机制来实现可靠性传输;最后在终止连接的过程中也要处理一些异常情况以保证顺利关闭连接。
虚拟内存是当今计算机系统中最重要的抽象概念之一,它的提出是为了更加有效地管理内存并且降低内存出错的概率。虚拟内存影响着计算机的方方面面,包括硬件设计、文件系统、共享对象和进程/线程调度等等,每一个致力于编写高效且出错概率低的程序的程序员都应该深入学习虚拟内存。 本文全面而深入地剖析了虚拟内存的工作原理,帮助读者快速而深刻地理解这个重要的概念。
在目前的技术选型中,Redis 俨然已经成为了系统高性能缓存方案的事实标准,因此现在 Redis 也成为了后端开发的基本技能树之一,Redis 的底层原理也顺理成章地成为了必须学习的知识。 Redis 从本质上来讲是一个网络服务器,而对于一个网络服务器来说,网络模型是它的精华,搞懂了一个网络服务器的网络模型,你也就搞懂了它的本质。 本文通过层层递进的方式,介绍了 Redis 网络模型的版本变更里程,剖析了其从单线程进化到多线程的工作原理,此外,还一并分析并解答了 Redis 的网络模型的很多抉择背后的思考,帮助读者能更深刻地理解 Redis 网络模型的设计。
分布式事务是分布式系统必不可少组成部分,基本上只要实现一个分布式系统就逃不开对分布式事务的支持。本文从分布式事务这个概念切入,尝试对分布式事务最核心的底层原理进行逐一的剖析,内容包括但不限于 BASE 原则、两阶段原子提交协议、三阶段原子提交协议、Paxos/Multi-Paxos 分布式共识算法的原理与证明、Raft 分布式共识算法和分布式事务的并发控制等内容。
本文将基于 Linux 平台来解析 Go netpoll 之 I/O 多路复用的底层是如何基于 epoll 封装实现的,从源码层层推进,全面而深度地解析 Go netpoll 的设计理念和实现原理,以及 Go 是如何利用 netpoll 来构建它的原生网络模型的。主要涉及到的一些概念:I/O 模式、用户/内核空间、epoll、Linux 源码、goroutine scheduler 等等,我会尽量简单地讲解,如果有对相关概念不熟悉的同学,还是希望能提前熟悉一下。
并发(并行),一直以来都是一个编程语言里的核心主题之一,也是被开发者关注最多的话题;Go 语言作为一个出道以来就自带 『高并发』光环的富二代编程语言,它的并发(并行)编程肯定是值得开发者去探究的,而 Go 语言中的并发(并行)编程是经由 goroutine 实现的,goroutine 是 golang 最重要的特性之一,具有使用成本低、消耗资源低、能效高等特点,官方宣称原生 goroutine 并发成千上万不成问题,于是它也成为 Gopher 们经常使用的特性。 Goroutine 是优秀的,但不是完美的,在极大规模的高并发场景下,也可能会暴露出问题,什么问题呢?又有什么可选的解决方案?本文将通过 runtime 对 goroutine 的调度分析,帮助大家理解它的机理和发现一些内存和调度的原理和问题,并且基于此提出一种个人的解决方案 — 一个高性能的 Goroutine Pool。