文章目录
注:部分参考《后端架构师技术图谱》
架构相关
存储
SQL
-
mysql
-
理论
- 《数据库的三大范式以及五大约束》
- 第一范式:数据表中的每一列(每个字段)必须是不可拆分的最小单元,也就是确保每一列的原子性;
- 第二范式(2NF):满足1NF后,要求表中的所有列,都必须依赖于主键,而不能有任何一列与主键没有关系,也就是说一个表只描述一件事情;
- 第三范式:必须先满足第二范式(2NF),要求:表中的每一列只与主键直接相关而不是间接相关,(表中的每一列只能依赖于主键);
- 《数据库的三大范式以及五大约束》
-
原理
-
- 两种类型最主要的差别就是Innodb 支持事务处理与外键和行级锁
-
InnoDB
-
优化
-
- 原则上就是缩小扫描范围。
-
索引
-
聚集索引, 非聚集索引
-
MyISAM 是非聚集,InnoDB 是聚集
-
复合索引
-
文中有一处错误:
-
对于复合索引,在查询使用时,最好将条件顺序按找索引的顺序,这样效率最高; select * from table1 where col1=A AND col2=B AND col3=D 如果使用 where col2=B AND col1=A 或者 where col2=B 将不会使用索引
- 原文中提到索引是按照“col1,col2,col3”的顺序创建的,而mysql在按照最左前缀的索引匹配原则,且会自动优化 where 条件的顺序,当条件中只有 col2=B AND col1=A 时,会自动转化为 col1=A AND col2=B,所以依然会使用索引。
-
-
自适应哈希索引(AHI)
-
explain
-
系列文章
- 《Mysql使用系列》
- 《MySQL存储引擎比较》
- 读写分离模式
- 分片模式
- 《分库分表需要考虑的问题及方案》
- 中间件: 轻量级:sharding-jdbc、TSharding;重量级:Atlas、MyCAT、Vitess等。
- 问题:事务、Join、迁移、扩容、ID、分页等。
- 事务补偿:对数据进行对帐检查;基于日志进行比对;定期同标准数据来源进行同步等。
- 分库策略:数值范围;取模;日期等。
- 分库数量:通常 MySQL 单库 5千万条、Oracle 单库一亿条需要分库。
- 《MySql分表和表分区详解》
- 分区:是MySQL内部机制,对客户端透明,数据存储在不同文件中,表面上看是同一个表。
- 分表:物理上创建不同的表、客户端需要管理分表路由。
- 《分库分表需要考虑的问题及方案》
-
-
tidb
NoSQL
- redis
- leveldb
- rocksdb
- memcache
- pika
FS
- hdfs
- seaweedfs
- ceph
搜索
分布式相关
-
Zookeeper
-
Etcd
-
分布式架构
-
扩展性设计
- 《架构师不可不知的十大可扩展架构》
- 总结下来,通用的套路就是分布、缓存及异步处理。
- 《可扩展性设计之数据切分》
- 水平切分+垂直切分
- 利用中间件进行分片如,MySQL Proxy。
- 利用分片策略进行切分,如按照ID取模。
- 《说说如何实现可扩展性的大型网站架构》
- 分布式服务+消息队列。
- 《大型网站技术架构(七)–网站的可扩展性架构》
- 《架构师不可不知的十大可扩展架构》
-
CAP 与 BASE 理论
- 《从分布式一致性谈到CAP理论、BASE理论》
- 一致性分类:强一致(立即一致);弱一致(可在单位时间内实现一致,比如秒级);最终一致(弱一致的一种,一定时间内最终一致)
- CAP:一致性、可用性、分区容错性(网络故障引起)
- BASE:Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)
- BASE理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。
- 《从分布式一致性谈到CAP理论、BASE理论》
-
分布式锁
- 《分布式锁的几种实现方式》
- 基于数据库的分布式锁:优点:操作简单、容易理解。缺点:存在单点问题、数据库性能够开销较大、不可重入;
- 基于缓存的分布式锁:优点:非阻塞、性能好。缺点:操作不好容易造成锁无法释放的情况。
- Zookeeper 分布式锁:通过有序临时节点实现锁机制,自己对应的节点需要最小,则被认为是获得了锁。优点:集群可以透明解决单点问题,避免锁不被释放问题,同时锁可以重入。缺点:性能不如缓存方式,吞吐量会随着zk集群规模变大而下降。
- 《基于Zookeeper的分布式锁》
- 清楚的原理描述 + Java 代码示例。
- 《jedisLock—redis分布式锁实现》
- 基于 setnx(set if ont exists),有则返回false,否则返回true。并支持过期时间。
- 《Memcached 和 Redis 分布式锁方案》
- 利用 memcached 的 add(有别于set)操作,当key存在时,返回false。
- 《分布式锁的几种实现方式》
-
稳定性 & 高可用
- 《聊聊高并发系统之限流特技-1》
- 《聊聊高并发系统限流特技-2》
- 《高并发之服务降级与熔断》
- 《系统设计:关于高可用系统的一些技术方案》
- 可扩展:水平扩展、垂直扩展。 通过冗余部署,避免单点故障。
- 隔离:避免单一业务占用全部资源。避免业务之间的相互影响 2. 机房隔离避免单点故障。
- 解耦:降低维护成本,降低耦合风险。减少依赖,减少相互间的影响。
- 限流:滑动窗口计数法、漏桶算法、令牌桶算法等算法。遇到突发流量时,保证系统稳定。
- 降级:紧急情况下释放非核心功能的资源。牺牲非核心业务,保证核心业务的高可用。
- 熔断:异常情况超出阈值进入熔断状态,快速失败。减少不稳定的外部依赖对核心服务的影响。
- 自动化测试:通过完善的测试,减少发布引起的故障。
- 灰度发布:灰度发布是速度与安全性作为妥协,能够有效减少发布故障。
- 《关于高可用的系统》
- 设计原则:数据不丢(持久化);服务高可用(服务副本);绝对的100%高可用很难,目标是做到尽可能多的9,如99.999%(全年累计只有5分钟)。
监控
- Open-Falcon
- Promethues
链路跟踪
日志
- ElasticSeach
- Logstash
- Kibana
- Filebeat
- 日志搜集
队列
- Kafka
- 《kafka数据可靠性深度解读》
- 《Kafka 设计与原理详解》
- 《深入学习Kafka:Leader Election - Kafka集群Leader选举过程分析》
- Kafka系列文章
- 《Kafka设计解析(一)- Kafka背景及架构介绍》
- 《Kafka设计解析(二)- Kafka High Availability (上)》
- 《Kafka设计解析(三)- Kafka High Availability (下)》
- 《Kafka设计解析(四)- Kafka Consumer设计解析》
- 《Kafka设计解析(五)- Kafka性能测试方法及Benchmark报告》
- 《Kafka 设计解析(六):Kafka 高性能关键技术解析》
- 《Kafka 设计解析(七):流式计算的新贵 Kafka Stream》
- 《Kafka 设计解析(八):Kafka 事务机制与 Exactly Once 语义实现原理》
- 《Kafka技术内幕&Kafka权威指南读书笔记系列》
- RocketMQ
- RabbitMQ
- NSQ
- MQ对比
中间件
-
Web Server
- Nginx
- 《Ngnix的基本学习-多进程和Apache的比较》
- Nginx 通过异步非阻塞的事件处理机制实现高并发。Apache 每个请求独占一个线程,非常消耗系统资源。
- 事件驱动适合于IO密集型服务(Nginx),多进程或线程适合于CPU密集型服务(Apache),所以Nginx适合做反向代理,而非web服务器使用。
- 《nginx与Apache的对比以及优缺点》
- nginx只适合静态和反向代理,不适合处理动态请求。
- 《百万并发下的Nginx优化》
- 《Nginx 中文文档》
- 《Ngnix的基本学习-多进程和Apache的比较》
- OpenResty
- 官方网站
- 《浅谈 OpenResty》
- 通过 Lua 模块可以在Nginx上进行开发。
- agentzh 的 Nginx 教程
- Tengine
- Apache Httpd
- Nginx
-
- Tomcat
- 架构原理
- Tomcat
-
-
-
- 《TOMCAT原理详解及请求过程》
- 《Tomcat服务器原理详解》
- 《Tomcat 系统架构与设计模式,第 1 部分: 工作原理》
- 《四张图带你了解Tomcat系统架构》
- 《JBoss vs. Tomcat: Choosing A Java Application Server》
- Tomcat 是轻量级的 Serverlet 容器,没有实现全部 JEE 特性(比如持久化和事务处理),但可以通过其他组件代替,比如Spring。
- Jboss 实现全部了JEE特性,软件开源免费、文档收费。- 调优方案
- 《TOMCAT原理详解及请求过程》
-
-
-
-
- 《Tomcat 调优方案》
- 启动NIO模式(或者APR);调整线程池;禁用AJP连接器(Nginx+tomcat的架构,不需要AJP);- 《tomcat http协议与ajp协议》
- 《AJP与HTTP比较和分析》
- AJP 协议(8009端口)用于降低和前端Server(如Apache,而且需要支持AJP协议)的连接数(前端),通过长连接提高性能。
- 并发高时,AJP协议优于HTTP协议。
- Jetty
- 《Tomcat 调优方案》
-
-
-
- 《Jetty 的工作原理以及与 Tomcat 的比较》
- 《jetty和tomcat优势比较》
- 架构比较:Jetty的架构比Tomcat的更为简单。
- 性能比较:Jetty和Tomcat性能方面差异不大,Jetty默认采用NIO结束在处理I/O请求上更占优势,Tomcat默认采用BIO处理I/O请求,Tomcat适合处理少数非常繁忙的链接,处理静态资源时性能较差。
- 其他方面:Jetty的应用更加快速,修改简单,对新的Servlet规范的支持较好;Tomcat 对JEE和Servlet 支持更加全面。
- 《jetty和tomcat优势比较》
- 《Jetty 的工作原理以及与 Tomcat 的比较》
-
微服务相关
-
RPC
- 《从零开始实现RPC框架 - RPC原理及实现》
- 核心角色:Server: 暴露服务的服务提供方、Client: 调用远程服务的服务消费方、Registry: 服务注册与发现的注册中心。
- 《分布式RPC框架性能大比拼 dubbo、motan、rpcx、gRPC、thrift的性能比较》
- 《RPCX浅析》
- 《从零开始实现RPC框架 - RPC原理及实现》
大数据相关
语言相关
-
Golang
- 内存分配原理
- 《编写可维护Go语言代码建议》
- 《Go语言充电站》
- 《golang源码分析》
- 《go语言学习》
- 《Golang GC的实现原理》
- 《深入理解 Go map:赋值和扩容迁移》
- 《Golang协程的实现原理》
- 《golang的协程调度-硬核原理》
- 《Golang并发模型:轻松入门流水线模型》
- 《Goroutine并发调度模型深入之实现一个协程池》
- 《Goroutine并发调度模型深度解析之手撸一个协程池》
- 《Go优质项目推荐》
- 《Golang平滑重启》
- 《请问sync.Pool有什么缺点?》
- 《Go 1.13中 sync.Pool 是如何优化的?》
- 《 Go 可视化性能分析工具》
- 《聊聊 Go Socket 框架 Teleport 的设计思路》
-
PHP
-
Java
Linux系统相关
- 《linux系列学习》
- 《linux命令系列》
- 《Linux工具快速教程》
- 《Linux select()详解》
- 《最全面的linux信号量解析》
- 《Linux 文件系统剖析》
- 《Linux中查看系统资源占用情况的命令》
- 《 深入理解Linux网络技术内幕》
网络相关
-
OSI 七层协议
-
TCP/IP
-
HTTP
-
HTTP2.0
- 《HTTP 2.0 原理详细分析》
- 《HTTP2.0的基本单位为二进制帧》
- 利用二进制帧负责传输。
- 多路复用。
- HTTPS
- 《https原理通俗了解》
- 《这样理解HTTPS更容易》
- 使用非对称加密协商加密算法
- 使用对称加密方式传输数据
- 使用第三方机构签发的证书,来加密公钥,用于公钥的安全传输、防止被中间人串改。
- 《八大免费SSL证书-给你的网站免费添加Https安全加密》
-
网络模型
- 《web优化必须了解的原理之I/o的五种模型和web的三种工作模式》
- 五种I/O模型:阻塞I/O,非阻塞I/O,I/O复用、事件(信号)驱动I/O、异步I/O,前四种I/O属于同步操作,I/O的第一阶段不同、第二阶段相同,最后的一种则属于异步操作。
- 三种 Web Server 工作方式:Prefork(多进程)、Worker方式(线程方式)、Event方式。
- 《select、poll、epoll之间的区别总结》
- select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的。
- select 有打开文件描述符数量限制,默认1024(2048 for x64),100万并发,就要用1000个进程、切换开销大;poll采用链表结构,没有数量限制。
- select,poll “醒着”的时候要遍历整个fd集合,而epoll在“醒着”的时候只要判断一下就绪链表是否为空就行了,通过回调机制节省大量CPU时间;select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,而epoll只要一次拷贝。
- poll会随着并发增加,性能逐渐下降,epoll采用红黑树结构,性能稳定,不会随着连接数增加而降低。
- 《select,poll,epoll比较 》
- 在连接数少并且连接都十分活跃的情况下,select和poll的性能可能比epoll好,毕竟epoll的通知机制需要很多函数回调。
- 《深入理解Java NIO》
- NIO 是一种同步非阻塞的 IO 模型。同步是指线程不断轮询 IO 事件是否就绪,非阻塞是指线程在等待 IO 的时候,可以同时做其他任务
- 《BIO与NIO、AIO的区别》
- 《两种高效的服务器设计模型:Reactor和Proactor模型》
- 《web优化必须了解的原理之I/o的五种模型和web的三种工作模式》
-
Epoll
-
Java NIO
-
kqueue
-
连接和短连接
-
框架
- 《Netty原理剖析》
- Reactor 模式介绍。
- Netty 是 Reactor 模式的一种实现。
- 零拷贝(Zero-copy)
- 《对于 Netty ByteBuf 的零拷贝(Zero Copy) 的理解》
- 多个物理分离的buffer,通过逻辑上合并成为一个,从而避免了数据在内存之间的拷贝。
- 序列化(二进制协议)
- 《对于 Netty ByteBuf 的零拷贝(Zero Copy) 的理解》
- 《Netty原理剖析》
-
Hessian
- 《Hessian原理分析》 Binary-RPC;不仅仅是序列化
-
Protobuf
-
- 《Protobuf协议的Java应用例子》 Goolge出品、占用空间和效率完胜其他序列化类库,如Hessian;需要编写 .proto 文件。
- 《Protocol Buffers序列化协议及应用》
- 关于协议的解释;缺点:可读性差;
- 《简单的使用 protobuf 和 protostuff》
- protostuff 的好处是不用写 .proto 文件,Java 对象直接就可以序列化。
- 《简单的使用 protobuf 和 protostuff》
- 《Protobuf协议的Java应用例子》 Goolge出品、占用空间和效率完胜其他序列化类库,如Hessian;需要编写 .proto 文件。
数据结构算法相关
-
数据结构
-
队列
-
-
非阻塞队列:ConcurrentLinkedQueue(无界线程安全),采用CAS机制(compareAndSwapObject原子操作)。
-
阻塞队列:ArrayBlockingQueue(有界)、LinkedBlockingQueue(无界)、DelayQueue、PriorityBlockingQueue,采用锁机制;使用 ReentrantLock 锁。
-
-
-
集合
-
链表、数组
- 《Java集合详解–什么是List》
-
字典、关联数组
-
栈
- 《java数据结构与算法之栈(Stack)设计与实现》
- 《Java Stack 类》
- 《java stack的详细实现分析》
- Stack 是线程安全的。
- 内部使用数组保存数据,不够时翻倍。
-
树
- 《二叉树》
- 每个节点最多有两个叶子节点。
- 《二叉树》
-
完全二叉树
- 《完全二叉树》
- 叶节点只能出现在最下层和次下层,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树。
-
-
左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
-
-
- 二叉查找树(Binary Search Tree),也称有序二叉树(ordered binary tree),排序二叉树(sorted binary tree)。
- 《浅谈算法和数据结构: 七 二叉查找树》
-
- 《最容易懂得红黑树》
- 添加阶段后,左旋或者右旋从而再次达到平衡。
- 《浅谈算法和数据结构: 九 平衡查找树之红黑树》
- 《最容易懂得红黑树》
-
-
MySQL是基于B+树聚集索引组织表
-
- B+树的叶子节点链表结构相比于 B-树便于扫库,和范围检索。
-
-
-
LSM(Log-Structured Merge-Trees)和 B+ 树相比,是牺牲了部分读的性能来换取写的性能(通过批量写入),实现读写之间的平衡。 Hbase、LevelDB、Tair(Long DB)、nessDB 采用 LSM 树的结构。LSM可以快速建立索引。
-
-
B+ 树读性能好,但由于需要有序结构,当key比较分散时,磁盘寻道频繁,造成写性能较差。
-
LSM 是将一个大树拆分成N棵小树,先写到内存(无寻道问题,性能高),在内存中构建一颗有序小树(有序树),随着小树越来越大,内存的小树会flush到磁盘上。当读时,由于不知道数据在哪棵小树上,因此必须遍历(二分查找)所有的小树,但在每颗小树内部数据是有序的。
-
《LSM树(Log-Structured Merge Tree)存储引擎》
-
极端的说,基于LSM树实现的HBase的写性能比MySQL高了一个数量级,读性能低了一个数量级。
-
优化方式:Bloom filter 替代二分查找;compact 小数位大树,提高查询性能。
-
Hbase 中,内存中达到一定阈值后,整体flush到磁盘上、形成一个文件(B+数),HDFS不支持update操作,所以Hbase做整体flush而不是merge update。flush到磁盘上的小树,定期会合并成一个大树。
-
-
-
-
- 经常用于大规模数据的排重检查。
- 《Java Bitset类》
- 《Java BitSet(位集)》
-
-
-
- 《Java中的经典算法之选择排序(SelectionSort)》
- 每一趟从待排序的记录中选出最小的元素,顺序放在已排好序的序列最后,直到全部记录排序完毕。
- 《Java中的经典算法之选择排序(SelectionSort)》
-
- 《冒泡排序的2种写法》
- 相邻元素前后交换、把最大的排到最后。
- 时间复杂度 O(n²)
- 《冒泡排序的2种写法》
-
- 《坐在马桶上看算法:快速排序》
- 一侧比另外一侧都大或小。
-
- 《图解排序算法(四)之归并排序》
- 分而治之,分成小份排序,在合并(重建一个新空间进行复制)。
- 《图解排序算法(四)之归并排序》
-
- 《图解排序算法(三)之堆排序》
- 排序过程就是构建最大堆的过程,最大堆:每个结点的值都大于或等于其左右孩子结点的值,堆顶元素是最大值。
- 《图解排序算法(三)之堆排序》
-
- 《计数排序和桶排序》
- 和桶排序过程比较像,差别在于桶的数量。
- 《计数排序和桶排序》
-
- 《【啊哈!算法】最快最简单的排序——桶排序》
- 《排序算法(三):计数排序与桶排序》
- 桶排序将[0,1)区间划分为n个相同的大小的子区间,这些子区间被称为桶。
- 每个桶单独进行排序,然后再遍历每个桶。
-
- 按照个位、十位、百位、…依次来排。
- 《排序算法系列:基数排序》
- 《基数排序》
-
- 《二分查找(java实现)》
- 要求待查找的序列有序。
- 时间复杂度 O(logN)。
- 《java实现二分查找-两种方式》
- while + 递归。
- 《二分查找(java实现)》
-
分布式一致性算法
-
PAXOS
-
Zab
-
Raft
- 《Raft 为什么是更易理解的分布式一致性算法》
- 三种角色:Leader(领袖)、Follower(群众)、Candidate(候选人)
- 通过随机等待的方式发出投票,得票多的获胜。
- 《Raft图解》
- 《Raft 为什么是更易理解的分布式一致性算法》
-
Gossip
-
两阶段提交、多阶段提交
-