编程操作 · 复制集 · 分片集群 · 日常运维
数据库高级进阶课
从“单机玩具”到“企业级巨兽”
本节课重点理解“架构底层原理”,理清思路,下节课我们将带大家进入机房实战!
让 Python 替我们干活 (附带了解 Java)
一直在黑乎乎的终端里敲代码,或者使用图形化界面(如 Compass)手动点点点。
淘宝、抖音的后台,都是用 代码程序 自动连接数据库来存取数据的。
代码和数据库说的是“不同的语言”,它们是怎么沟通的呢?
只懂 Python 字典和语法
只懂 BSON 数据和数据库指令
什么是驱动? 驱动就像是一个翻译官。你用 Python 写一句“保存字典”,驱动会自动把它翻译成 MongoDB 听得懂的网络指令。
不管是哪种语言,想要连接数据库,第一件事都是提供服务器的“家庭住址”——连接字符串 (URI)。
mongodb://[username:password@]host[:port]/[database]
mongodb://,告诉系统这是在连接 MongoDB,不是 http 网页请求。
可选。如果数据库开启了密码,这里就要填:root:123456@
服务器在哪?默认端口是 27017(务必记住这个端口号!)。
虽然我们主攻 Python,但在企业里也会经常遇到 Java。Java 开发往往极其严谨。
new Document(),然后 .append("键", "值") 把数据塞进去。代码相对比较长。大数据时代的“瑞士军刀”
在数据处理、人工智能领域,Python 是绝对的统治者。
MongoDB 存储的是 BSON(类似 JSON 的文档格式)。
而在 Python 中,最常用的数据结构是字典 (Dictionary)。
student = {"name": "张三", "age": 20}。insert_one(student) 方法。Python 字典 MongoDB 文档
在代码中,找数据就像查户口一样,要一层一层往下找:
连通服务器
实例化 client = MongoClient('URI'),这就相当于建立了一根连接到数据库主机的网线。
选择数据库
通过 db = client['库名'] 找到你要操作的具体数据库。
选择集合
通过 col = db['集合名'] 获取存放数据的“表”,拿到表之后就可以直接进行 find() 或 insert() 操作了。
文心一言、通义千问是怎么变聪明的?
大家知道国产的“文心一言(百度)”或“通义千问(阿里)”吗?它们在训练前,需要吞噬互联网上几千亿个网页的数据。
下节实验课,我们将亲手用 Python 写一个简单的数据入库脚本,大家不用担心记不住具体代码。
打不死的数据库 (高可用架构原理)
单点故障 (SPOF)
如果我们只把 MongoDB 装在一台电脑上:
这就是真实企业环境绝对不允许的“单点故障”。
简单来说,就是“找几个分身”。俗话说,不要把鸡蛋放在同一个篮子里。
我们把同样的数据,同时存放在多台不同的服务器上。它们彼此之间通过网络连接,时刻保持数据一模一样(数据同步)。
高可用性 (High Availability): 只要有一台机器还活着,整个数据库服务就不会中断!
在一个标准的 MongoDB 复制集中,通常至少需要 3个节点。它们不是平等的,而是有明确的分工:
Primary
全场的“大Boss”。
Secondary
任劳任怨的“替补”。
Arbiter
只投票不干活的“裁判”。
在整个复制集中,有且只有一个主节点。
oplog(操作日志)。我是主节点,我不挂,谁敢称王!
一直在默默抄作业的替补
从节点是主节点的“影子”。
oplog 日记本,并在自己身上重演一遍,保证数据和主节点一模一样。这是一种极其特殊的节点角色。
从节点是如何做到和主节点数据完全一致的?秘密全在 Oplog 里。
Oplog (Operations Log) 是主节点上的一个特殊内部集合。它记录了所有对数据库进行写操作(Insert/Update/Delete)的详细动作记录,而不是直接搬运数据文件。
* 懂 MySQL 的同学可以把它类比为 Binlog。这是保证分布式系统数据一致性的核心基石。
节点之间默认每隔 2秒 互相发送网络心跳包检测对方状态。
如果连续 10秒 没收到老大的回复,小弟们就认为老大“宕机”了。
当主节点确认宕机后,剩下的节点不会傻等,马上开始“内部选举”流程:
某从节点 10 秒未收到主节点心跳,宣布旧的主节点死亡。
该从节点检查自己抄的作业是不是最新的。如果是,它就向所有人发拉票请求:“选我当老大!”
其他存活节点(包括仲裁者)进行投票。获得超过半数选票的节点,立即晋升为新主节点!系统恢复正常。
支撑了双十一海量并发的国产神级数据库。
享誉全球的国产开源分布式数据库。
虽然大家今天学的是 MongoDB,但分布式系统高可用的底层逻辑是相通的!
如果是真正生产环境,我们需要准备 3 台不同的服务器。为了大家后续实验方便,我们通常会在一台虚拟机上开3个不同的端口来模拟3台机器。
(同一台机器上,只需建不同的数据目录和日志目录即可)
mongod.conf要让普通的单机 MongoDB 变成复制集的一员,关键是在它的配置文件里加上一行暗号:
这代表:“我要加入一个名叫 `myrs` (my replica set) 的帮派”。
把三个实例的配置文件都加上这个帮派名,然后分别把它们启动起来。
启动后,它们还是一盘散沙,互相不认识。我们需要连接到其中一个(比如 27017),执行初始化命令进行结拜。
执行完 rs.initiate() 后,这台机器就成了老大。
接着,用 rs.add("IP:27018") 把小弟加进来,用 rs.addArb("IP:27019") 把仲裁者加进来,整个集群就大功告成了!
海量数据的终极破局之道 (横向扩展)
复制集解决了“机器坏了”的问题,但它解决不了“数据太多装不下”的问题。
假设我们每天产生 1TB 业务数据:
撑爆了!
“给机器吃大补丸”
换更贵的 CPU、插满 128G 内存、买最贵的 100TB 企业级硬盘。
缺点:物理极限无法突破,且极度昂贵!
“人多力量大”
不买超级电脑,而是买几十台便宜的普通电脑,把数据切成小块分给它们存。
优点:理论上容量无限大!(这就是分片思想)
想象一本记录了全中国 14 亿人信息的《中国人口名录》。
把海量数据进行“切块”,分散存放在多台机器上的技术,就叫分片。
要构建一个完美的分片系统,我们需要三种角色的配合。这有点像一个大型图书馆的运作模式:
——“一排排的书架”
真正存放数据块的地方。为了防止某个书架烧毁数据丢失,每个 Shard 本身往往都是一个复制集。
——“图书索引目录”
记录了“哪段数据放在哪个书架上”的地图指引。非常关键!
——“前台图书管理员”
路由器。你的 Python 代码只连它。它查完目录,帮你去对应书架拿书。
Shard 是实际负责存储用户数据的实例。
数据被切块后,总得有人知道 A块放在了 Shard-1,B块放在了 Shard-2 吧?
Config Server 就是干这个的。它专门存储集群的元数据(Metadata)和分片路由表。
咱们的 Python 代码,到底连接谁呢?难道要把所有 Shard 的 IP 都写进代码里吗?
交警指路,内部逻辑对开发者透明
大西瓜怎么切才均匀?我们需要一把特殊的刀 —— 片键 (Shard Key)。
片键就是集合中的一个(或几个)字段名。MongoDB 将根据你指定的这个字段的值,来决定把这条数据扔到哪个 Shard 去。
如果选错了片键,会导致有的 Shard 塞满数据累死,有的 Shard 空空如也闲死(这在专业上叫数据倾斜)。
MongoDB 提供了两种主要的切西瓜策略 ⬇️
存 Age: 0 ~ 20岁的人
存 Age: 21 ~ 40岁的人
存 Age: 41岁 ~ MAX 的人
以数字或字母的连续区间来划分。
系统会对你选的片键值先做一次 Hash(哈希算法运算),算出一个极其随机的散列值,然后再根据这个散列值存入不同的 Shard。
就像掷骰子一样随机,确保绝对的负载均衡
由于分片集群需要的组件非常多,真正部署起来是一个繁琐的体力活。其基本顺序如下:
首先搭建好“地图大脑”,需以配置服务器模式(且推荐为复制集)启动。
启动若干个存数据的分片实例(最好每个也是复制集)。
启动路由节点,启动时在配置文件告诉它 Config Server 的IP地址。
登录 Mongos 使用 sh.addShard() 把所有书架纳入系统,并设置片键启用分片。
MongoDB 是较早践行“分片集群”理念的 NoSQL。
今天,我国自主研发的顶级关系型数据库(NewSQL)也将分布式分片理念做到了极致,比如华为的 GaussDB(高斯) 或是 PingCAP 的 TiDB。
掌握分片思想,走遍分布式天下都不怕!
数据备份 · 性能监控 (DBA的保命技能)
有了前面学的高可用和分片架构就万事大吉了吗?No!
再牛的架构也会面临:黑客入侵勒索、程序员手滑写错代码删库、双十一流量突增卡顿。
大数据时代的“系统医生”
复制集防的是“物理硬件故障”(机器烧了,替补顶上)。
但它绝对防不住“人为手残误删”(手滑在主库执行了 db.dropDatabase(),由于 Oplog 极速同步机制,所有从节点也会在几毫秒内跟着把数据删得干干净净!)。
将数据导出成文件的冷备份,是避免删库跑路的最后一道防线!
MongoDB 官方提供了自带的导出工具:mongodump。它可以把数据库里的数据直接导成 BSON 二进制文件存到硬盘目录下。
参数解析:
-h:指定目标服务器的 IP 和端口。-d:指定要备份哪个库(例如这里备份了 school 库)。-o:指定备份文件导出的硬盘存放路径。天塌下来了(数据被新人误删了),DBA 不慌不忙拿出了昨天半夜用 mongodump 导出的备份文件夹,开始执行“时光倒流”。
* 该命令会读取指定的 BSON 文件夹内容,重新一条一条插入到数据库中,恢复元气。
客户投诉:“你们的系统太卡了,点个查询转半天圈圈!”
作为工程师,你不能靠瞎猜来修 Bug,必须用数据说话。我们要看:
寻找导致卡顿的真正元凶
mongostat 是 MongoDB 自带的最经典命令行监控工具,它就像医院的心电图机器,每秒钟刷新一次数据库健康状态。
你会看到什么关键指标:
insert/query/update/delete: 每秒执行了多少次增删改查。如果这四个数值突然飙高至几万,说明流量洪峰来了!conn: 当前连接数。vsize / res: 占用虚拟内存和物理内存的大小。告别枯燥的纯字符黑框终端
虽然 mongostat 很好用,但真正的现代企业(包含使用国产数据库的企业),更喜欢用漂亮的大屏来监控。
理解 Driver 翻译官的作用。掌握使用 PyMongo 库,利用 Python 字典极其丝滑地操作 MongoDB 文档数据。
防“单机故障宕机”的方案。记住“一主、一从、一仲裁”,理解 Oplog 抄作业机制和自动心跳选举机制。
防“容量撑爆硬盘”的方案。理清 Shard(存)、Config(脑)、Mongos(路由) 三大组件配合,以及片键切分数据的原理。
懂冷备份防误删跑路,掌握 mongodump 与 mongorestore。了解用 mongostat 看“心电图”排查系统卡顿性能。
下节课,我们将把这些架构原理转化为代码和命令!
准备好迎接机房实战吧!
现在是 Q & A 答疑环节,有问题随时提问。