虚拟地址

页表

用大白话精准说:这个对照表叫「页表」

1. 基础存放位置

页表本身,存在【物理内存(内存条)】里

操作系统给每个进程都单独造一张页表,老老实实放在内存条。

2. 加速小缓存(TLB)

CPU 嫌每次查内存页表太慢,自己内部带了个高速小缓存:

TLB(页表高速缓存)存在【CPU 内部】

常用的「虚拟地址→物理地址」映射,先存在 TLB 里,秒查。

3. 完整流程举例

  1. 程序访问虚拟地址
  2. CPU 先看自己内部 TLB 有没有对照表
  3. 没有就去 物理内存 里找这个进程的页表
  4. 翻译成真实物理地址,再拿数据

极简总结

  • 完整大对照表(页表)👉 内存条
  • 加速临时对照表(TLB)👉 CPU 里面

硬盘中的虚拟内存

先拆大白话,再讲原理

一、先懂:平时的「内存不够」痛点

电脑 物理内存(内存条 RAM) 容量有限(比如 8G/16G),开太多软件、大程序时,物理内存会塞满,不够用了。

二、什么是「把硬盘一部分设为虚拟内存」?

操作系统从 硬盘 划出一块专属空间(Windows 叫页面文件 pagefile.sys,Linux 叫 Swap 分区),冒充”临时内存”,和物理内存凑一起用,这块硬盘空间就叫 虚拟内存/交换空间

关键区分:

  • 物理内存:内存条,速度极快
  • 虚拟内存(硬盘客串的):硬盘空间,速度慢很多

三、结合你刚才问的「虚拟地址+页表」串起来

  1. 每个进程的 虚拟地址空间 很大(比如 32 位进程 4G、64 位极大),远超物理内存条大小;
  2. 页表不仅能把 虚拟地址 → 物理内存 映射;
  3. 当物理内存装满时,OS 会把 暂时不用的数据/页面,搬到 硬盘的虚拟内存区域
  4. 页表里改个标记:这个虚拟地址对应的内容,现在不在内存条,在 硬盘 Swap 里
  5. 程序要用这块数据时,CPU 缺页异常,OS 再把数据从硬盘拷回物理内存。

四、为什么能这么做?核心底层能力

  1. MMU + 页表的映射灵活性

    页表可以自由定义:虚拟页 → 物理内存页 硬盘 Swap 位置,硬件支持地址映射 + 缺页中断;

  2. 局部性原理

    程序不会同时用到所有内存数据,大部分页面是闲置的,适合把冷数据挪去硬盘;

  3. OS 调度管理

    操作系统负责挑选”没人用的数据”换出、”要用的数据”换入,对上层程序完全透明——程序感知不到自己在用硬盘当内存

五、优缺点直白说

好处:

  • 解决物理内存不足,能开更多/更大软件;
  • 扩容逻辑内存空间,让进程拥有超大虚拟地址空间。

坏处:

  • 硬盘速度比内存慢几十~几百倍,频繁读写虚拟内存会 电脑卡顿、磁盘占用高

六、一句话总结

就是 OS 利用 页表映射 + 缺页中断,把硬盘一块区域当「低配慢速临时内存」兜底,解决物理内存条容量不够的问题,对软件无感、系统自动调度。

虽然日常都叫「虚拟内存」,其实是完全不同的两个概念


① 概念一:CPU/进程的【虚拟地址空间(逻辑虚拟内存)】

  • 每个程序眼里独立的一大片逻辑地址(假地址)
  • 页表 → MMU 映射
  • 本身只是「编号规则」,不关硬盘啥事
  • 目的:隔离进程、统一地址编排、方便内存管理

② 概念二:硬盘客串的【页面文件/Swap(兜底虚拟内存)】

  • 从硬盘划一块空间,当低配内存用
  • 物理RAM不够时,把冷数据挪去这里
  • 速度很慢,用来救急扩容
  • Windows:pagefile.sys,Linux:swap分区

一句话分清

1️⃣ 虚拟地址(逻辑虚拟内存):软件看的「假地址编号」,架构层面;
2️⃣ 硬盘虚拟内存(Swap/页面文件):内存不够时拿来凑数的「硬盘临时缓存」,存储兜底层面。


关联关系(串你之前的问题)

页表既可以把虚拟地址映射到:

  • ✅ 物理内存条
  • 硬盘Swap/页面文件

所以才把两个东西缠在一起,叫法又撞名,最容易晕😵

一文搞懂MySQL各类索引

先定基础前提:默认讲InnoDB引擎(MySQL最常用),先区分两大底层结构,再分功能分类讲所有索引,通俗不绕弯。

一、先搞懂:索引底层两大数据结构

1. B+树索引(InnoDB默认主流)

  • 特点:多路平衡查找树,磁盘IO少、范围查询(> < between like 前缀匹配)极强、排序分组快
  • 适用:日常99%场景,MySQL默认聚簇/主键/普通/唯一索引底层都是B+树

2. Hash索引(Memory引擎常用,InnoDB不原生支持)

  • 特点:哈希表结构,等值查询超快,但不支持范围查询、排序、模糊匹配,有哈希冲突
  • 适用:纯精准=匹配场景,业务极少用

二、InnoDB核心架构:聚簇索引 vs 非聚簇索引

1. 聚簇索引(Clustered Index)

核心定义:数据行本身就是索引叶子节点,索引和真实数据绑定在一起

  • InnoDB必须有且只有1个聚簇索引
  • 规则优先级:
    1. 有主键 → 主键就是聚簇索引
    2. 无主键,有唯一非空索引 → 该唯一索引当聚簇索引
    3. 都没有 → MySQL自动生成隐藏rowid作为聚簇索引
  • 优点:主键查询、范围查询速度极快;
  • 缺点:主键不宜用随机UUID(页分裂严重)

2. 二级索引 / 辅助索引(Secondary Index)

除聚簇索引外,所有其他索引都叫二级索引

  • 二级索引叶子节点不存完整数据,只存「主键值」
  • 查询流程(回表):二级索引找主键 → 用主键去聚簇索引找完整行数据
  • 我们建的普通索引、唯一索引,全都属于二级索引

三、按业务功能划分:4种常用二级索引

1. 主键索引(Primary Key Index)

  • 特性:唯一+非空,一张表只有1个
  • 底层:InnoDB里主键索引 = 聚簇索引
  • 示例:id INT PRIMARY KEY

2. 普通索引(Normal Index)

  • 最基础的二级索引,允许重复值、允许NULL
  • 只提升查询效率,无唯一性约束
  • 示例:INDEX idx_name (name)

3. 唯一索引(Unique Index)

  • 特性:值全局唯一,允许1个NULL(NULL不比较)
  • 作用:既加速查询,又约束字段不重复
  • 和主键区别:一张表可以有多个唯一索引,唯一索引不是聚簇索引(二级索引)
  • 示例:UNIQUE INDEX idx_phone (phone)

4. 联合索引/复合索引

多个字段合建一个B+树索引,遵循最左前缀原则,属于普通/唯一索引的组合形态


四、关键概念快速汇总对照表

索引名称 底层结构 是否聚簇 唯一性 核心特点
聚簇索引 B+树 ✅ 唯一1个 唯一非空 叶子存整行数据
主键索引 B+树 ✅ 就是聚簇 唯一非空 一张表仅1个
二级索引 B+树 ❌ 辅助 看具体类型 叶子只存主键,需要回表
普通索引 B+树 ❌ 二级 可重复 仅加速查询
唯一索引 B+树 ❌ 二级 全局唯一 加速+去重约束
B+树索引 B+树结构 看归属 看归属 支持范围/排序/模糊前缀
Hash索引 哈希表 等值唯一 =快,不支持范围查询

五、新手必懂3个高频知识点

  1. 回表查询
    查二级索引字段,没覆盖需要完整数据 → 拿着主键再查聚簇索引,多一次IO,叫回表;
    解决:建覆盖索引,直接在二级索引拿到所有需要字段,不用回表。

  2. 为什么InnoDB推荐自增主键?
    聚簇索引是有序B+树,自增主键递增插入,无页分裂、性能最好;随机主键会频繁挪动数据。

  3. Hash索引为什么不用?
    业务大多需要> < like %前缀% order by,Hash完全不支持,只有精准等值查询才快,局限性太大。


六、一句话极简总结

  1. B+树/Hash:是索引的「底层存储结构」;
  2. 聚簇/二级:是InnoDB的「索引存储形态」(聚簇存全数据,二级存主键);
  3. 主键/普通/唯一:是「业务功能分类」,除主键外都是二级B+树索引。

K8S

Kubernetes (K8s) 入门到实战教程

Kubernetes(简称K8s)是开源容器编排平台,用于自动化部署、扩缩容、管理容器化应用,是云原生核心技术。本教程从概念、环境搭建、核心操作、实战部署逐步展开,零基础可上手。

一、K8s核心概念(必懂)

1. 集群架构(Master + Worker)

  • Master节点(控制平面):管理整个集群
    • API Server:集群唯一入口,处理所有操作请求
    • etcd:分布式键值存储,保存集群所有配置与状态
    • Scheduler:调度Pod到合适的Worker节点
    • Controller Manager:管理各类控制器(如Deployment、ReplicaSet),确保资源状态符合预期
  • Worker节点(工作节点):运行应用容器
    • kubelet:节点代理,与Master通信,管理本机Pod
    • kube-proxy:维护网络规则,实现Service的负载均衡与代理
    • 容器运行时:如Docker、containerd,负责运行容器

2. 核心资源对象

对象 作用 核心特点
Pod 最小部署单元,包含1个或多个容器 共享网络/存储,生命周期短暂
Deployment 管理无状态应用,控制Pod副本、滚动更新/回滚 自动创建ReplicaSet,保障高可用
Service 为Pod提供稳定网络访问与负载均衡 屏蔽Pod IP变化,支持ClusterIP/NodePort/LoadBalancer
ReplicaSet 确保指定数量Pod副本运行 由Deployment管理,不直接操作
Namespace 资源隔离(如default、kube-system) 划分集群资源,避免命名冲突
ConfigMap/Secret 存储配置/敏感信息(密码、密钥) 解耦配置与镜像,Secret加密存储
PV/PVC 持久化存储(Pod删除后数据不丢失) PV是存储资源,PVC是Pod对存储的申请

二、本地环境搭建(新手首选)

方案1:Minikube(单节点,最易上手)

1
2
3
4
5
6
7
8
9
10
# 1. 安装Minikube(以Linux为例,Windows/macOS参考官网)
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# 2. 启动集群(指定驱动,如docker)
minikube start --driver=docker

# 3. 验证集群
kubectl cluster-info # 查看集群信息
kubectl get nodes # 查看节点状态(Ready为正常)

方案2:Kind(Docker内多节点集群)

1
2
3
4
5
6
7
8
# 1. 安装Kind
go install sigs.k8s.io/kind@v0.20.0

# 2. 创建集群
kind create cluster --name my-cluster

# 3. 验证
kubectl cluster-info

核心工具:kubectl(必装)

1
2
3
4
5
6
7
# Linux安装
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/

# 验证
kubectl version --client

三、kubectl常用命令(高频操作)

1. 资源查看

1
2
3
4
5
6
7
kubectl get pods                          # 查看Pod
kubectl get deployments # 查看Deployment
kubectl get services (svc) # 查看Service
kubectl get nodes # 查看节点
kubectl get namespaces (ns) # 查看命名空间
kubectl get all -n kube-system # 查看kube-system下所有资源
kubectl describe pod <pod名> # 查看Pod详细信息(排错必备)

2. 资源创建/更新(推荐yaml声明式)

1
2
3
4
5
6
# 基于yaml文件创建/更新资源
kubectl apply -f <yaml文件>

# 命令式创建(快速测试)
kubectl create deployment nginx --image=nginx:alpine # 创建Deployment
kubectl expose deployment nginx --port=80 --type=NodePort # 暴露Service

3. 扩缩容与更新

1
2
3
4
5
6
7
8
9
10
11
# 扩容Deployment到5个副本
kubectl scale deployment nginx --replicas=5

# 滚动更新镜像(无 downtime)
kubectl set image deployment nginx nginx=nginx:1.25

# 查看更新状态
kubectl rollout status deployment nginx

# 回滚到上一版本
kubectl rollout undo deployment nginx

4. 日志与容器交互

1
2
3
4
5
6
7
8
# 查看Pod日志
kubectl logs <pod名>

# 实时查看日志
kubectl logs -f <pod名>

# 进入Pod容器执行命令
kubectl exec -it <pod名> -- /bin/sh

5. 资源删除

1
2
3
kubectl delete -f <yaml文件>
kubectl delete deployment <deployment名>
kubectl delete pod <pod名> --grace-period=0 --force # 强制删除

四、实战:部署Nginx应用(完整流程)

步骤1:编写Deployment yaml(nginx-deploy.yaml)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
spec:
replicas: 3 # 3个Pod副本
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80

步骤2:编写Service yaml(nginx-svc.yaml)

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx # 匹配Deployment的Pod标签
ports:
- protocol: TCP
port: 80 # Service端口
targetPort: 80 # 容器端口
type: NodePort # 节点端口,外部可访问

步骤3:部署并访问

1
2
3
4
5
6
7
8
9
10
11
# 1. 部署Deployment
kubectl apply -f nginx-deploy.yaml

# 2. 部署Service
kubectl apply -f nginx-svc.yaml

# 3. 查看资源状态
kubectl get pods,svc

# 4. 获取访问地址(Minikube)
minikube service nginx-svc --url # 输出可访问的URL,浏览器打开即可

五、进阶核心知识点

1. Service类型详解

  • ClusterIP(默认):仅集群内部可访问,用于内部服务通信
  • NodePort:在每个节点开放固定端口,外部可通过节点IP:NodePort访问
  • LoadBalancer:云环境专用,自动创建负载均衡器,分配公网IP
  • ExternalName:将Service映射到外部域名(如example.com

2. 持久化存储(PV/PVC)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# PVC申请存储(nginx-pvc.yaml)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi

# Deployment挂载PVC(修改nginx-deploy.yaml)
spec:
containers:
- name: nginx
image: nginx:alpine
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
persistentVolumeClaim:
claimName: nginx-pvc

3. 配置管理(ConfigMap/Secret)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# ConfigMap(nginx-config.yaml)
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
index.html: |
<h1>Hello K8s!</h1>

# Deployment挂载ConfigMap
spec:
containers:
- name: nginx
volumeMounts:
- name: config
mountPath: /usr/share/nginx/html
volumes:
- name: config
configMap:
name: nginx-config

六、生产环境部署(kubeadm)

1. 环境准备(所有节点)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 关闭swap
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab

# 安装容器运行时(containerd)
sudo apt update
sudo apt install -y containerd
sudo systemctl enable --now containerd

# 安装kubeadm、kubelet、kubectl
sudo apt install -y apt-transport-https ca-certificates curl
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update
sudo apt install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

2. 初始化Master节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sudo kubeadm init \
--apiserver-advertise-address=<Master节点IP> \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.29.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16

# 配置kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 安装网络插件(Calico)
kubectl apply -f https://docs.projectcalico.org/v3.27/manifests/calico.yaml

3. Worker节点加入集群

1
2
3
4
5
# Master节点生成加入命令
kubeadm token create --print-join-command

# Worker节点执行输出的命令
sudo kubeadm join <MasterIP>:6443 --token <token> --discovery-token-ca-cert-hash <hash>

七、学习资源推荐

  1. 官方文档(最权威)https://kubernetes.io/zh/docs/
  2. 实战教程:Kubernetes in Action(书籍)、极客时间《深入剖析Kubernetes》
  3. 在线实验:Katacoda(https://www.katacoda.com/)、Play with Kubernetes

需要我基于上述教程,帮你生成一份可直接复制运行的K8s快速部署脚本(含Nginx Deployment/Service/ConfigMap)吗?