golang技术栈后端知识图谱
2025-05-22 15:43:31 0 举报
AI智能生成
golang技术栈后端知识图谱,持续更新
作者其他创作
大纲/内容
语言
map
hmap
元素数量、hash种子、桶个数、溢出桶个数、指向桶的指针、扩容旧桶指针、
bmap
kv存储、溢出桶地址(链表)
hash计算
低位hash计算桶、高位hash计算桶内位置
查找过程:匹配低位hash、低位hash,在桶和溢出桶中寻找值
扩容
装载因子过高:元素数量/桶数量>6.5
增量扩容:桶数量翻倍、渐进式迁移
分配新桶数组;标记旧桶;每次插入\删除时迁移一两个到新桶、迁移完成旧桶释放
并发不安全
数据一致性的保证
基础数据结构需要保持高效
解决方案:分片map,减少锁竞争
context
作用
传播取消信号(单向只读channel)
超时控制
值传递
底层实现:cancelCtx
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{}
Err() error
Value(key interface{}) interface{}
}
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{}
Err() error
Value(key interface{}) interface{}
}
goroutine
本质
由go运行时管理
初始栈空间2KB
调度成本低,上线下文切换比OS线程快10-100倍
GMP模型
内存模型
内存布局
栈内存:协程的独立栈、自动管理无需手动释放
堆内存:动态分配、垃圾回收、指针引用
全局数据区:存储全局变量;程序启动时分配生命周期与程序相同。
内存分配TCMalloc
分级分配
mcache
mcentral
mheap
内存逃逸:内存从栈到堆
go build -gcflags="-m" main.go
go build -gcflags="-m" main.go
场景
闭包函数、大块内存、指针逃逸、变量大小不确定
垃圾回收
三色标记:根对象开始扫描、递归扫描引用;清除阶段;并发执行
GC关键参数
堆内存增长2倍触发GC
强制触发GC
监控GC:runtime.ReadMemStats获取HeapAlloc
性能优化
减少堆分配:利用逃逸分析优化
控制内存增长:避免大对象频繁的分配释放;设置合理的GOGC
手动管理,不建议尝试
encoding/json
延迟解析:json.RawMessage
反射
常见性能问题诊断
CPU占用高:CPU Profile—使用top查看热点函数—list查看具体代码
内存占用高:heap profile—使用top查看内存分配—使用list看分配电
goroutine泄漏:采集协程profile—分析协程数量;检查协程创建点—确定报协程有退出机制
锁竞争:采集mutex profile—使用top查看锁等待时间-优化锁粒度或者使用无锁结构
性能调优工具
pprof
分析类型
CPU分析
内存分析
阻塞的分析
goroutine分析
查看命令
top:最消耗资源的函数
list函数名:查看函数具体的代码和耗时
web:生成调用图
peek:看函数及其他调用者的信息
traces:查看所有采样站
trace
关键指标
协程的生命周期
调度延迟
网络/系统调用阻塞
锁竞争
gc活动
分析视图
时间线可视化
协程分析
网络阻塞分析
同步阻塞分析
系统调用阻塞分析
调度延迟分析
常见问题
CPU使用率高:无限循环、复杂代码、频繁序列化和反序列化
内存问题:协程泄漏、全局变量积累、未关闭资源
协程泄漏:通道channel阻塞、无限循环、waitGroup使用不当、未处理的context取消:func leak(ctx context.Context) {
go func() {
select { // 只监听一个channel,没有处理ctx.Done()
case <-time.After(time.Minute):
fmt.Println("done")
}
}()
}
go func() {
select { // 只监听一个channel,没有处理ctx.Done()
case <-time.After(time.Minute):
fmt.Println("done")
}
}()
}
并发的问题:死锁
GC压力:频繁GC、GC停顿时间长
GC时间长
原因
堆内存过大
对象图复杂
高频率分配内存
设置了不合理的GC参数
优化方案
减少内存分配,使用协程池;避免在热度路径上分配内存
优化数据结构:使用值类而非指针类;减少不必要的指针分配;
调整GC参数
优化架构:大对象拆分为小对象;减少全局对象
网络和IO瓶颈:连接池太少
并发模型
GMP:runtime包查询GMP数据
channel高级模式
工作池
func workerPool(workers int, tasks <-chan Task) {
var wg sync.WaitGroup
wg.Add(workers)
for i := 0; i < workers; i++ {
go func(id int) {
defer wg.Done()
for task := range tasks {
process(task)
}
}(i)
}
wg.Wait()
}
var wg sync.WaitGroup
wg.Add(workers)
for i := 0; i < workers; i++ {
go func(id int) {
defer wg.Done()
for task := range tasks {
process(task)
}
}(i)
}
wg.Wait()
}
超时控制组合
func fetchWithTimeout(url string, timeout time.Duration) (string, error) {
ch := make(chan string, 1)
go func() { ch <- fetch(url) }()
select {
case resp := <-ch:
return resp, nil
case <-time.After(timeout):
return "", fmt.Errorf("timeout")
}
}
ch := make(chan string, 1)
go func() { ch <- fetch(url) }()
select {
case resp := <-ch:
return resp, nil
case <-time.After(timeout):
return "", fmt.Errorf("timeout")
}
}
多路复用
调度器Scheduler
调度器性能优化
GOMAXPROCS设置
避免调度抖动
减少频繁的goroutine创建
控制goroutine栈大小
调度关键机制
工作窃取:1先检查全局队列;2从其他P的队列尾部偷取一半G;3检查网络轮询器;4最后检查定时器
系统调用处理
自旋线程优化
调度器性能优化
诊断调度问题
查看调度器的统计
使用trace工具
特殊场景处理
长时间运行的计算通过:runtime.Gosched()主动让出
实时性要求高的任务:runtime.LockOSThread()锁定到当前的线程
大量I/O密集型任务:控制并发量:sem := make(chan struct{}, 1000) ;func() { <-sem }()
演进历史
sync包
Mutex
基本结构
数据结构:state锁状态标志;sema信号量
状态位解析:32位的state包含多个标志
waitersCount:等待锁的goroutine数量
starving:是否处于饥饿模式
Woken:是否有被唤醒的goroutine
locked:锁是否被持有
工作模式
正常模式
新来的g与被唤醒的g竞争
新来的g更容易获取锁
等待超过1ms的g转为饥饿模式
饥饿模式
锁直接交给等待队列的头部
新来的g不会尝试获取锁,直接进入队列
源码解析(未完)
lock流程:自旋尝试;更新等待计数;尝试获取锁;必要时进入休眠
高级技巧
尝试获取锁 TryLock
常见陷阱
锁重入导致死锁:两次Lock
忘记解锁
复制锁
调优建议
减少锁粒度
缩短临界区
读写分离
避免嵌套
WaitGroup
信号量+计数器
信号量+计数器
计数器为负数,会panic
底层实现
信号量机制
内存顺序保证
Once
基本结构
数据结构
互斥锁
执行状态标识
核心方法
原子检查done标志;若未执行过,获取锁进入慢路径;双重检查done防止竞争
pool对象池
基本结构
核心结构
net/http
os
文件
文件基本操作
目录操作
文件信息和权限
文件路径
环境变量和进程
环境变量的操作
进程管理
文件锁
内存映射文件
临时文件和目录
信号Signal
扩容
slice
当前容量<1024,新容量=旧容量*2
如果当前铜容量>1024,新容量=旧容量*1.25
最终会根据元素类型和内存对齐要求进行调整
map(map本身是指针)
触发条件
装载因子(元素数量/桶数量)>6.5
溢出桶过多
Redis
数据结构
字符串String
简单动态字符SDS
自动空间预分配+惰性释放
二进制安全,可以储存任意二进制数据
兼容部分C字符串函数
struct sdshdr {
int len; // 已使用长度
int free; // 未使用长度
char buf[]; // 实际字符串数据
};
int len; // 已使用长度
int free; // 未使用长度
char buf[]; // 实际字符串数据
};
哈希hash
底层实现
ziplist:元素数量少且值小
特点
连续内存,紧凑存储
变长编码
自动转化:超过阈值自动转化hashtable
线性查找On复杂度
插入删除可能导致后续元素内存重新分配
结构
<zlbytes> <zltail> <zllen> <entry> <entry> ... <entry> <zlend>
zlbytes (4字节):整个ziplist占用的字节数
zltail:到达最后一个entry的偏移量
zllen:entry的数量(当数量超过2^16-1时,需要遍历才能知道长度)
entry:存储的实际数据
zlend:标记结束,固定字符0xFF
hashtable
渐进式rehash、链式hash、自动缩容
typedef struct dictht {
dictEntry **table; // 哈希桶数组
unsigned long size; // 桶数量
unsigned long sizemask; // 掩码(计算索引)
unsigned long used; // 已用桶数量
}
渐进式rehash、链式hash、自动缩容
typedef struct dictht {
dictEntry **table; // 哈希桶数组
unsigned long size; // 桶数量
unsigned long sizemask; // 掩码(计算索引)
unsigned long used; // 已用桶数量
}
列表List
ziplist:元素量少时使用
quicklist(On复杂度)
typedef struct quicklist {
quicklistNode *head; // 头节点
quicklistNode *tail; // 尾节点
unsigned long count; // 总元素数
unsigned long len; // 节点数(ziplist 数量)
int fill: 16; // 单个 ziplist 大小限制(来自 list-max-ziplist-size)
unsigned int compress: 16; // LZF 压缩深度(0 表示不压缩)
} quicklist;
集合Set
intset:元素数量少(数量<512)且都是整数,log(n)
特点
内存高效:连续存储整数,无额外指针开销
有序存储:元素升序
动态编码
二分查找
类型升级:当插入更大范围的数时,自动升级整个编码方式
数据结构:<encoding> <length> <contents>
encoding:指定整数类型(2字节、4字节、8字节的整数)
length:集合中的元素数量
contents:实际存储的整数数组
编码升级:当插入新的整数超出编码范围,整个集合都会转换为更大的整数类型,升级的过程是不可逆的
hashtable
有序集合ZSet
ziplist:数量少
skiplist+hashtable
skiplist logN复杂度+多层链表+上层是下层的子集+双向链表
typedef struct zskiplistNode {
robj *obj; // 成员对象
double score; // 分值
struct zskiplistNode *backward; // 后退指针
struct zskiplistLevel {
struct zskiplistNode *forward; // 前进指针
unsigned int span; // 跨度
} level[]; // 层
} zskiplistNode;
typedef struct zskiplistNode {
robj *obj; // 成员对象
double score; // 分值
struct zskiplistNode *backward; // 后退指针
struct zskiplistLevel {
struct zskiplistNode *forward; // 前进指针
unsigned int span; // 跨度
} level[]; // 层
} zskiplistNode;
位图Bitmap
HyperLogLog
地理空间
流
异地集群同步
原生方案
主从复制+代理层
异地机房A(主)+异地机房B(从)+代理层
redis集群跨机房
增强方案
双活同步
云服务商方案:通过DTS服务配置同步
网络优化:服务专线
数据一致性保证
比较两地key数量
使用RDB文件校验
容灾切换
自动故障检测
手动切换步骤
事务处理
Lua脚本
大Key问题解决
数据拆分
数据压缩
使用更合适的数据结构
设置过期时间
客户端缓存
一致性实现
主从复制数据一致性
同步方式:RDB全量同步+增量同步
一致性机制:心跳检测、写传播、存储最近主节点写命令
一致性级别
异步复制
半同步复制:阻塞客户端直到一定数量节点同步完
故障转移
持久化机制
RDB:经过压缩的二进制文件
AOF
每条命令同步一次
每秒同步(默认)
操作系统决定
集群架构
主从复制
集群
数据分片
gossip协议
故障转移:节点选举
性能
单节点qps:10万+
优化建议
管道技术(Pipeline)减少RTT
Pipeline批量操作命令
大规模数据的导入导出
实时的统计、计数
批量更新配置
低延迟的写密集型应用
连接池的使用
避免大键(超过10KB)
合理设置持久化策略
使用批量操作命令
双主写集群数据同步方案
redis集群,不是真正的双主是分片
第三方双主方案
两集群同步数据,CRDT合并冲突
智能路由
应用层双写
基于Raft/Paxos
分布式锁
普通
进阶RedLock
一次尝试从多个节点获取锁
如果获取失败,向所有节点发起释放锁
常用中间件
sentinel-go
流量控制
策略
QPS限流策略:滑动窗口统计单位时间内的请求数量
直接拒绝模式
qps超过阈值直接拒绝请求
滑动窗口数据结构LeapArray:循环数组
核心结构
窗口长度、采样数量、每个采样片的长度、环形数据本身
匀速排队模式
漏桶算法 Leaky Bucket
并发数限流:计数器
关联限流:针对关联资源设置限流
通过资源间的关联关系实现限流
场景:优先级控制、资源依赖控制、多维度限流(用户+接口组合)+复杂业务场景下的级联限流
熔断、降级
熔断器
关闭、搬开、打开
触发条件:错误率、超时率
降级性能指标
监控响应时间、错误率
隔离:各接口、服务隔离开,确保某个资源的过载不影响到其他的服务
隔离原理
资源隔离:独立规则+独立统计数据
线程池的隔离
不同资源独立线程池,结合协程池
信号量隔离
每个资源有独立的并发计数器
核心思想
资源抽象
独立统计
规则隔离
上下文传递
优势
故障隔离
资源保障
优先级控制
系统稳定性
系统自适应保护
实时监测与数据分析
实时数据监控:流量、熔断、降级统计指标
历史数据分析:支持对历史数据的查询和分析
ETCD
键值存储:简单的键值(key-value)存储接口
一致性:使用 Raft 共识算法保证数据一致性
高可用:支持集群部署,自动故障转移
持久化:数据持久化到磁盘
观察者模式:可以监视键的变化
租约机制:支持键的 TTL 自动过期
事务支持:支持多键原子操作
TiDB
整体架构
TiDB Server:无状态SQL计算层
TiKV:分布式事务型键值存储引擎
PD(Placement Driver):元数据管理和调度中心
TiFlash(可选):列式存储分析引擎
数据的分布于分片
region机制
数据分片和调度的基本单位
数据分片和调度的基本单位
数据按照range划分为多个region
默认region的大小是96M
每个region有多个副本
副本通过Raft保持一致性
数据路由流程
客户端缓存region路由信息
发送请求到正确的region Leader
如果region分裂或者迁移,返回错误并更新路由
定期从PD刷新路由
事务实现
两段式提交
乐观锁机制(默认)
支持快照隔离和读已提交隔离
高可用的设计
TiDB Server:无状态,可快速扩容
leader自动选举;少数副本故障不影响可用性
PD:基于raft实现自身可用性
TiFlash
列式存储引擎,通过Raft实现TiKV到TiFlash同步,毫秒级延时
实时分析处理 HTAP
通过Raft Learner机制异步复制数据
支持MPP执行模式
核心组件
TiDB Server
核心功能
SQL解析和优化
分布式执行计划生成
事务协调
兼容mysql协议
关键特性
无状态设计,水平扩容
支持标准sql和mysql协议
智能查询优化器(CBO)
sql语句->逻辑优化->统计信息收集->物理优化->分布式执行计划
支持二级索引和聚簇索引
┌───────────────────────┐
│ MySQL Protocol │
└──────────┬────────────┘
│
┌──────────▼────────────┐
│ SQL Layer │
│ ┌─────────────────┐ │
│ │ Parser │ │
│ └────────┬────────┘ │
│ ┌────────▼────────┐ │
│ │ Optimizer │ │
│ └────────┬────────┘ │
│ ┌────────▼────────┐ │
│ │ Executor │ │
│ └─────────────────┘ │
└──────────┬────────────┘
│
┌──────────▼────────────┐
│ Distributed Exec │
└───────────────────────┘
│ MySQL Protocol │
└──────────┬────────────┘
│
┌──────────▼────────────┐
│ SQL Layer │
│ ┌─────────────────┐ │
│ │ Parser │ │
│ └────────┬────────┘ │
│ ┌────────▼────────┐ │
│ │ Optimizer │ │
│ └────────┬────────┘ │
│ ┌────────▼────────┐ │
│ │ Executor │ │
│ └─────────────────┘ │
└──────────┬────────────┘
│
┌──────────▼────────────┐
│ Distributed Exec │
└───────────────────────┘
TiKV存储层
核心功能
分布式键值存储引擎
多版本并发控制(MVCC)
一致性协议Raft
分布式事务
关键特性
基于RocksDB的高性能存储
数据自动分片
支持ACID事务
数据自动均匀和故障恢复
┌───────────────────────────────────────┐
│ TiKV │
│ ┌───────────────────────────────────┐ │
│ │ Raft Group │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ │ Leader │ │ Follower│ │ Follower│ │
│ │ └─────────┘ └─────────┘ └─────────┘ │
│ └───────────────────────────────────┘ │
│ ┌───────────────────────────────────┐ │
│ │ RocksDB │ │
│ │ ┌───────┐ ┌───────┐ ┌───────┐ │ │
│ │ │ CF │ │ CF │ │ CF │ ... │ │
│ │ └───────┘ └───────┘ └───────┘ │ │
│ └───────────────────────────────────┘ │
└───────────────────────────────────────┘
│ TiKV │
│ ┌───────────────────────────────────┐ │
│ │ Raft Group │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ │ Leader │ │ Follower│ │ Follower│ │
│ │ └─────────┘ └─────────┘ └─────────┘ │
│ └───────────────────────────────────┘ │
│ ┌───────────────────────────────────┐ │
│ │ RocksDB │ │
│ │ ┌───────┐ ┌───────┐ ┌───────┐ │ │
│ │ │ CF │ │ CF │ │ CF │ ... │ │
│ │ └───────┘ └───────┘ └───────┘ │ │
│ └───────────────────────────────────┘ │
└───────────────────────────────────────┘
PD
核心功能
集群元数据管理
全局ID分配
负载均衡调度
故障检测和恢复
关键特性
基于etcd实现的高可用
实时监控集群状态
智能调度
热点区域自动识别和分散
主要职责
存储region路由信息
监控每个TiKV节点状态
调度Region副本的分布
分配全局唯一的时间戳
分表
水平分表(Range分区)
Hash分表
列表分表(按照离散列值进行分表)
非/聚簇索引自动分片
混合事务与分析处理架构
核心特性
双存储引擎:TiKV、TiFlash
毫秒级延时
智能路由
技术实现原理
行列混合存储(列存压缩)
MPP计算引擎:分布式并行计算
1、查询解析:tidb解析sql并生成逻辑计划
2MPP优化:将适合的操作转化为MPP算子
3任务分发:协调者节点拆分查询到各TiFlash节点
4并行执行:各几点处理数据分片
5、合并结果
系统设计与架构
微服务设计原则
基础原则
单一职责
独立部署
去中心化数据管理
服务间通信
容错和弹性
可观测
API网关
交互设计原理
松耦合通信
容错设计:熔断
API契约优先
数据管理原则
数据所有权
最终一致性模式
运维原则
可观测性:指标采集QPS、延迟、错误率;日志结构json+trece串联;跨服务调用链追踪;
基础设施即代码:CICD部署
RPC
本质理解:像调用本地函数一样调用远程服务
调用方无需感受服务部署位置;隐藏底层网络通信;支持跨语言;
核心组件
客户端
序列化协议
json
ProtoBuf
Thrift
接口定义
协议传输
代码生成
压缩
传输层压缩:整个数据包压缩
协议层压缩:对结构化数据进行压缩
性能技巧
对数据包小于1KB的禁用压缩
客户端和服务端压缩协议相同
监控压缩率
压缩会使cpu负载升高
协议结构
消息头
协议标识、消息类型、方法名长度
消息体:TLV 字段唯一标识;字段类型;字段长度(可选);字段值(变长)
关键设计优势
边长字段,空间效率高
未知字段跳过
线性扫描即可解码
网络传输
TCP长链接
HTTP/2支持多路复用
服务端
关键设计考量
服务发现
客户端发现,客户端查询注册中心:Netflix Eureka
服务端发现,通过LB访问,
容错机制
性能优化
连接池、压缩、批处理
服务治理
服务注册和发现
配置管理
降级熔断
限流、负载均衡
服务监控与日志
服务安全
服务版本管理
服务追踪和链路分析
自动化运维
服务治理平台
意义
提升系统稳定性
提升开发效率
提升用户体验
支持业务扩展
分布式系统——脑裂
脑裂产生的原因
网络分区:集群节点之间链接故障
节点故障
心跳检测失败
脑裂后果
数据不一致
服务冲突
资源竞争
举例--mysql主主复制
网络断开后A、B两节点无法通信
A认为B宕机持续写入;B认为A宕机持续写入;
网络恢复后,两节点不一致并且合并有冲突
Mysql
mysql
核心架构
分层架构
连接层:连接池、身份验证、线程管理
服务层:sql接口、解析器、优化器、缓存
存储引擎:插件式架构(InnoDB)
文件系统层:数据文件、日志文件
关键线程
核心后台线程
负责异步IO操作
事务回滚和undo日志清理
脏页刷新
深度解析
InnoDB
事务支持ACID特性
MVCC多版本并发控制
聚簇索引:数据存储方式
行级锁:共享锁、排他锁、意向锁
缓冲池:LRU算法、预读机制
高性能设计要点
索引优化
B+树:3-4层支持千万数据
索引选择原则
索引失效场景
复合索引:最左前缀原则
查询优化
临时表优化,避免磁盘
临时表常见用途
核心作用
数据缓冲:原始数据和目标数据的过渡层
数据转换:存储预处理后的中间结果
性能优化:分解复杂操作、提高查询效率
解耦合:隔离源系统和目标系统,降低直接依赖
集群部署指南
单机部署
主从复制:主服务处理写操作,从服务器负责读请求
主主复制
组复制:多主复制数据库集群;共识算法Paxos变种实现数据一致性
mysql InnoDB 集群:多主复制、自动故障切换、负载均衡
云数据库服务:
容器化部署:使用容器技术打包mysql和部署,高度的可移植性
性能优化
使用合适的索引
避免使用select*
避免在where后使用函数
使用limit限制使用行数
使用explain分析查询计划
使用合适的数据类型
避免使用or来优化查询
尽量使用覆盖索引
ACID实现原理
A 原子性
Redo log和Undo log,事务提交成功Redo呗被持久化,事务提交失败Undo 恢复数据
C 一致性
约束检查
触发器
存储过程和应用程序的逻辑
事务日志
I 隔离性
锁
行级锁
共享锁
排他锁
意向锁
多版本并发控制
隔离级别
读未提交
读已提交
可重复读
串行化
D 持久性
redo log
双层缓存
强制写磁盘
数据文件和日志文件持久存储
一致性实现
单机
ACID
事务日志:Redolog和Undo log
锁:表锁和行锁
多版本并发控制MVCC
双写缓冲
主从集群
复制的基础架构
复制模式
异步复制
半同步
组复制
二进制日志Binlog:
sql语句、记录行变化、智能混合
sql语句、记录行变化、智能混合
关键技术
先同步Binlog到从库,在提交事务
全局事务标识
定期数据校验
ES
核心组件
集群
跨节点自动数据分布和负载均衡
通过唯一名称表示
自动发现和故障检测机制
节点Node
类型
主节点:负责集群管理-索引创建删除、节点加入移除
数据节点:存储数据并执行数据相关操作
协调节点:路由请求、聚合结果
Ingest节点:预处理文档。数据写入前:提取、转换、加载
机器学习节点:运行机器学习任务
通信节点
使用Zen Discovery模块进行节点发现与故障检测
节点自动发现:新节点加入集群是自动识别其他成员
主节点选举:协调集群的领导者选举过程
故障检测:监控节点健康状态并触发恢复机制
集群状态同步:维护并传播集群元数据变更
基于Gossip协议的状态传播
去中心化分布式通信协议
Push模式:节点主动将信息推送给随机的邻居
Pull模式:节点定期随机选择邻居节点拉取信息
Push-Pull混合:结合两者优势
索引
物理实现:分成多个分片;每个分片是一个完成的Lucene索引实例
Lucene
分段存储机制
索引被划分为多个不可变的段(Segment),每个段包含完整的倒排索引和文档数据
新文档先写入内存缓冲区,定期刷新生成新段
段文件采用压缩存储
动态合并优化
后台通过合并策略自动合并小段
合并过程会重组数据:消除删除文档、优化压缩率、重建索引结构
采用分层合并策略控制IO消耗,优先合并类似大小的段
多类型索引并存
倒排索引:支持快熟词项查找
DocValues列式存储支持聚合排序
BKD树,高效处理数据范围和地理位置查询
内存磁盘协同
内存缓冲区加速实时写入
文件系统缓存(mmap)提升读取性能
多级缓存体系(节点、索引、段级)减少磁盘访问
压缩与编码优化
术语字典使用FST有限状态转化器压缩
到排列采用PDMC编码和跳跃表
文档数据分块压缩存储
特性:支持动态映射,通过_alias实现索引别名
动态映射:索引能自动识别并处理未预先定义的字段类型
分片
主分片:数据写入的入口点;数量在索引创建时固定;
副本分片:主分片的拷贝;提供高可用和读取的负载均衡,数量可以动态调整
分布式特性实现
保持一致性
写一致性、读一致性、乐观并发控制
脑裂防护
状态管理
集群状态
所有索引和节点的状态;仅由主节点更新并传播
发布机制
版本化更新;两阶段提交
数据分布和复制
写流程
客户端->协调节点->文档路由到主分片->主分片斜土本地->复制到副本分片->副本分片确认->主分片返回成功
读流程
客户端->协调节点->轮询所有相关分片(主、副)->合并结果->返回客户端
分片分配的策略
平衡分配:磁盘容量、分片数量、节点负载
感知配置:机架感知、热温冷架构
存储引擎
Lucene核心
倒排索引
段
文档储存
ES存储优化
Refresh:默认将1秒你的缓存写入新段;近实时搜索NRT
Flush:将段持久化到磁盘;清空事务日志
Merge:后台段合并优化
高可用
故障恢复
副本提升:主节点故障是自动提升副本
分片重分配:节点下线后自动重新平衡
滚动升级
逐个节点重启更新
确保集群持续可用
网络
计算机网络基础
OSI七层模型和TCP/IP四层模型
OSI七层模型
物理层
数据链路层:节点间的可靠传输,wifi,以太网
网络层:路径选择和逻辑地址管理,ip协议
传输层:端到端的通信,TCP\UDP
会话层:建立、管理和终止会话
表示层:数据格式转换、加密解密
应用层:HTTP、FTP
TCP/IP四层模型
网络接口层:物理层和数据链路层
网络层:网络层
传输层:传输层
应用层:应用层、会话层、表示层
关键网络设备
集线器:物理层,广播数据包效率低
交换器:工作在数据链路层,基于MAC地址转发数据,支持全双工
路由器:在网络层工作,基于IP地址进行路由选择
网关:在不同协议间进行转化,常用于应用层
负载均衡器:分发流量到多个服务器,提高系统的可用性和性能
网络性能指标
带宽:单位时间内传输的数据量,bps
吞吐量:实际传输的数据量,受网络拥塞等因素的影响
延迟:数据包从源到目的地的传输时间
抖动:延时的变化程度,影响实时应用体验
丢包率:在传输过程中丢失数据包的比例
网络协议
IP协议
IPv4
32位地址,约43亿个地址
IPv6
128位地址,几乎无限的地址空间,改进了路由和安全特性
子网划分与CIDR
使用子网掩码划分网络,CIDR(无类比域间路由)简化地址分配
传输层协议
TCP
特点
可靠保证
流量控制
拥塞控制
全双工通信
典型应用:web浏览器、文件传输FTP、电子邮件SMTP、远程登录SSH
UDP
特点
无连接通信
尽最大努力交付
低延时
无拥塞控制
支持多播、广播
典型应用:实时音视频zoom、DNS查询、网络游戏、传感器数据上报、应用广播
应用层协议
HTTP超文本传输、HTTPS:HTTP+SSL/TLS
DNS:域名解析
FTP-文件传输协议 SFTP-基于ssh的安全文件传输协议
SMTP-发送邮件
MQTT-轻量级的发布订阅消息传输协议 WebSocket:提供全双工通信,适用于实时Web应用
网络性能优化
缓存策略
压缩和优化:压缩和多路复用
链接管理:Keep-Alive复用链接;连接池
负载均衡:轮询;基于地理位置;最少连接
网络架构设计
分层架构
接入层:路由器、交换机
汇聚层:聚合接入层流量、进行策略控制
核心层:提高吞吐量、低延时的主干链接
高可用和容灾设计
冗余设计:多路径、多设备避免单点
负载均衡:分发流量
故障切换:自动检测切换
异地多活
微服务中的网络
服务发现
API统一网关:统一入口、处理认证、路由、限流等
服务间通信:同步(http,grpc)和异步(消息队列)
软件定义网络和网络功能虚拟化
SDN:将控制平面与数据平面分离,铜鼓控制器集中管理网络
NFV:讲网络功能(防火墙、负载均衡)虚拟化,运行在通用硬件上
网络安全
常见的攻击类型
DDos攻击:通过大量请求消耗尽目标资源
MITM:拦截和篡改通信双方数据
SQL注入、XSS:web应用层面的攻击
端口出扫描和暴力破解:探测和尝试破解网络服务的访问权限
安全防护措施
防火墙:基于规则过滤流量、保护内部网络
入侵检测与防御系统:监控和阻止恶意活动
VPN:加密隧道
身份验证与授权:OAuth
加密技术:SSL
零信任架构
永不信任
始终验证
最小访问权限
持续监控
SocketIO模型:select、poll、epoll
IO基本概念
阻塞IO和非阻塞IO
同步IO和异步IO
Select模型
监控多个文件描述符的可读、可写、异常事件;用fd_set位图管理描述符;每次调用需要重新设置描述符;
缺点:单个进程监控的fd数量有限;效率On;需要频繁的上下文切换
Poll模型
pollfd结构体管理描述符;没有最大文件限制;事件类型更丰富;
线性扫描所有fd,效率低
epoll模型
使用红黑树管理fd,hash存储就绪事件;支持边缘触发(变更只通知一次)和水平触发(持续通知,默认)
CICD
更快、更安全、更高质量
更快、更安全、更高质量
概念
CI持续集成
定义:开发人员频繁合并变更到主分支,并通过自动化构建和测试快速验证变更。
目标:尽早发现错误;确保代码始终处于可部署状态
实践:代码提交后自动触发构建和测试;使用版本控制系统管理代码;快速反馈
工具:Jenkins
CD:持续交付/部署
持续交付
定义:代码通过自动化测试后随时可以手动部署到生成环境
持续部署
定义:代码通过所有测试后,自动部署生产环境,无需人工干预
关键实践:自动化监控和回滚;渐进式发布(金丝雀)
工具:ArgoCD、Spinnaker、Tekton、AWS CodePipeline
核心流程-流水线
代码提交
构建
自动化测试
部署测试环境
人工审批
部署生产
监控与回滚
优势
快速交付
减少人为错误
提高质量
降低风险
团队协作
持续性交付
核心目标
快速、频繁、可靠的软件发布
降低风险:通过小批量、渐进式的变更减少发布失败
缩短反馈周期
关键原则
自动化一切
持续集成
部署流水线
环境一致
版本控制一切
补充知识点
Redis
基础结构
string
SDS:空间预分配、惰性释放、二进制安全
list(先进先出)
双向链表
压缩列表(ziplist)
特点:内存紧凑数据结构,占用连续的内存空间。使用特点:数据总量小、数字数值/字符串长度小
使用限制:修改数据成本高;遍历效率低
实际的数据结构
<zlbytes总字节> <zltail最后数据偏移量> <zllen数据数量> <entry数据> <entry> ... <entry> <zlend结束位>
<prevlen上条数据长度用于反向遍历> <encoding当前数据长度> <content数据内容>
快速列表
结构:由多个压缩列表和一个双向链表组成。每个ziplist作为一个单独的内存块存储若干元素,双向链表用于连接多个ziplist,形成大的连续的空间。
set(键值对集合、无序唯一)
底层实现
hashTable:底层使用值为空的hash实现
intset:小规模数据
typedef struct intset {
uint32_t encoding; // 编码方式(int16, int32, int64)
uint32_t length; // 元素个数
int8_t contents[]; // 存储元素的数组
} intset;
uint32_t encoding; // 编码方式(int16, int32, int64)
uint32_t length; // 元素个数
int8_t contents[]; // 存储元素的数组
} intset;
升序便于二分查找;内存紧凑节省空间;
zset
底层实现
ziplist
skiplist + hashtable:skiplist根据分数快速查找到范围,hashtabe查询分数到元素的映射
skiplist跳表
hash
底层实现
ziplist
hastable
hash函数、hash冲突使用链表或者红黑树
持久化:RDB+AOF
数据库
mysql
分布式数据库
TDSql
tidb
分布式事务
ACID
一致性、原子性、隔离性、持久性
常用方案
两阶段提交:2PC
优缺点:一致性强;缺点:同步阻塞、单点故障、性能开销大
步骤
Prepare:准备阶段:协调者询问所有参与者是否可以提交事务;参与者执行事务,并记录日志;
commit:所有参与者同意,协调者通知所有参与者提交事务;否则回滚;
三阶段提交:3PC
优缺点:实现复杂,存在单点故障
步骤
Prepare:协调者发送准备请求;参与者执行事务并记录日志;
pre-commit:协调者发送预提交请求;接收者进入预提交状态;若所有参与者都进入预提交,则进入提交阶段,否则进入终止阶段。
commit:所有参与者确定预提交。协调者决定提交事务。若有超时未确认,协调者终止事务。参与者回滚释放资源。
TCC(基于补偿机制的分布式事务)
步骤
Try:协调者向参与者发送Try请求,要求预留资源。结果为成功或者失败。如果都成功,则进入commit;否则进入cancel阶段。
confirm确认阶段:协调者发送confirm请求,要求正式提交事务。参与者返回执行结果成功或者失败。
cancel阶段:如果try失败,则回滚
特点:高一致性、灵活、无阻塞。
实例
金融场景
try:冻结余额、冻结库存
confirm:扣减账户余额、扣减库存
cancel:解冻账户余额、解冻库存
补偿机制
日志记录:每个阶段操作都要记录日志
幂等设计
超时机制
故障恢复(通过日志)
幂等如何保证
方法
唯一标识:ID或者token
状态机
版本号
去重表
场景
支付扣款:网络抖动导致多次扣款,使用唯一的订单标识
订单系统
库存
用户注册
文件上传
Redis
特性
高可用
主从复制:主从架构、数据备份及数据同步、自动故障转移
哨兵模式:监控主节点状态并出发故障转移、哨兵本身也是集群避免单点故障
集群模式:数据分布多节点,单节点负责部分数据(适于横向扩展)、故障转移
持久化:AOF和RDB
客户端重定向与故障处理:
redis客户端具备重试机制
redis集群和哨兵模式下,客户端可以自动检测主节点变化,并且重新定向到新节点
网络分区
多派机制:拥有大部分分区的才能够继续提供服务
避免脑裂:每个主节点必须与其他节点保持通信
哨兵仲裁机制:只有拥有更多少哨兵同意的节点才能提升为主节点
内存数据库,读写性能高
redis集群轻松地支持横向扩展
数据分片:16384槽位
动态扩展、接管部分槽位
数据分布多个节点、并发处理请求
客户端自动感知集群结构,自动定位,支持重试
微服务拆分
基本原则
DDD
每个微服务应该有明确的业务能力边界
区分核心域、支撑域、通用域
统一语言
单一职责原则
每个微服务只关心特定功能
松耦合高内聚
避免数据共享、跨服务调用通过良好的接口定义
常见的拆分策略
业务能力拆分法
用户服务、订单服务、支付服务、库存服务
领域事件驱动拆分
世界业务中的关键事件(如订单已创建、支付已确认)、围绕事件的生产者和消费者,使用事件总线和消息队列实现服务间通信
数据隔离拆分
服务拥有自己的专属数据库
通过api访问数据而不是通过数据库
考虑数据的最终一致性
服务边界界定的考量因素
组织因素(康威定理)
技术因素
高频交互功能适合放在一起
技术的异构性:如不同的技术栈分开成独立的服务
扩展需求:不同的扩展要求的组件
演进因素
变更频率:变更频率差异大的应该独立
生命周期:临时性功能和核心功能应该拆分开
版本管理:独立发布需求强的
服务拆分评估指标
内聚度指标:功能内聚、数据内聚
耦合度指标:调用依赖(服务间同步调用数量)、事件依赖(服务间一步事件数量)、共享程度(共享数据库缓存等资源数量为0)
运维指标
独立部署能力
故障隔离性
监控粒度
拆分后的治理策略
服务通信设计:同步REST/grpc;异步消息队列
数据一致性的保证
长事务拆分成多个本地短事务
读写分离
事件溯源(通过事件重建状态)
服务演进策略
绞杀者模式
并行运行模式
特性开关
常见的拆分误区和解决方案
过度拆分
拆分不足
跨边界依赖问题
引用防腐层ACL
模型隔离:外部的服务模型(实体)-->防腐层(转换逻辑)-->本服务模型(领域对象)
协议转化
通信协议的转化:REST转grpc
数据格式的转化:XML转json
错误处理的标准化
依赖解耦
降低服务间的依赖
缓冲外部服务影响
提供模拟实现供测试使用
实现模式
适配器的模式
门面模式
设计要点
明确职责边界
应该处理:模型妆花、协议适配、错误转化、缓存策略、重试机制
不应该处理:业务逻辑,领域规则、业务流程
性能的考量
实现本地缓存减少外部调用
支持批量查询转化
异步阻塞设计
容错的设计
测试策略
单元测试
集成测试
契约测试考虑
演进和维护
版本管理策略
监控指标
重构信号
go并发模型
csp理论:不是通过共享内存来通信而是通过通信来共享内存。
轻量级线程
GMP模型,在用户态实现协程调度节省上下文切换
初始2KB
channel
select多路复用
监听多个channel处理最优先就绪的
sync包
sync.Mutex互斥锁
sync.RWMutex读写锁
sync.WaitGroup
sync.Once单次执行
并发模式
worker pool工作池
Fan-Out/Fan-In
微服务框架核心模块
1、通信模块
rpc框架:grpc、thrift
REST API:HTTP/HTTPSj接口暴露与管理
消息队列集成:kafka/pulsar
协议转化
服务治理模块
配置管理
监控告警
安全模块
数据管理
部署与扩展
测试迟支持
其他高级功能
rpc
协议
thrift
跨语言
二进制、json协议都支持
跨语言
内置rpc框架
服务定义
序列化
传输层:发送和接收(rcp、http)
协议层(数据编码、解码)
服务端
客户端
pb
二进制
需要搭配grpc
跨语言
生态完善、强大
操作系统
ipc进程间通信
信号量
共享内存
消息队列
管道
命名管道
套接字(网络)
线程间通信
共享变量
互斥锁
条件变量
事件
信号量
屏障

收藏
0 条评论
下一页