媒体文件(如图片、视频、语音信息、文档等)绝不会直接存储在关系型数据库或传统的 NoSQL 数据库(如键值存储或文档数据库)中。这是一种业界普遍遵循的最佳实践,对于像 WhatsApp 这样处理海量媒体内容的应用来说,更是必然的选择。
为什么不直接存储在数据库中?
性能瓶颈:
数据库不是为大文件设计的: 关系型数据库优化了结构化数据的存储和查询,而非大文件的存取。存储大文件会显著增加数据库的 I/O 负担,影响其核心功能(如事务、查询)的性能。
备份和恢复: 包含大量媒体文件的数据库会变得极其庞大,导致备份、恢复和维护变得非常缓慢和困难。
查询效率: 在大文件中进行查询效率低下,通常也缺乏专门的媒体处理能力。
存储成本高昂: 数据库存储通常比专门的文件存储解决方案昂贵得多,尤其是在需要高可用性和高性能的生产环境中。
可扩展性问题: 数据库的垂直扩展(增加服务器性能)有其上限,而存储媒体文件需要极强的水平扩展能力。
媒体处理功能缺失: 数据库不提供媒体文件所需的各种功能,如转码、缩略图生成、流媒体传输、CDN 集成等。
如何存储和引用媒体文件?
WhatsApp 采用的是典型的分离存储(Separate Storage)策略,即将媒体文件存储在专门的文件存储服务中,并在数据库中存储对这些文件的引用(URL 或路径)。
1. 实际媒体文件的存储位置
媒体文件会存储在分布式文件存储系统或对象存储服务中:
云对象存储服务: 这是最常见且推荐的解决方案。例如:
Amazon S3 (Simple Storage Service)
Google Cloud Storage
Azure Blob Storage
这些服务提供极高的可用性、持久性、可扩展性(PB 级存储)、成本效益和全球分布能力。它们还集成了 CDN(内容分发网络)功能,可以加速全球用户的媒体下载。
自建分布式文件系统: 对于像 Meta (Facebook) 这样规模的公司,它们可能拥有自己高度优化的自建分布式文件系统,例如基于 HDFS 或其他技术的集群,以实现更精细的控制和更高的成本效益。
内容分发网络 (CDN): 媒体文件(尤其是频繁访问的)通常 克罗地亚 whatsapp 数据库 会通过 CDN 进行分发。CDN 在全球部署边缘节点,将媒体内容缓存到离用户最近的服务器上,大大减少下载延迟和网络带宽消耗。
2. 数据库中的引用方式
在核心的 Messages 表中,存储的是指向这些外部媒体文件的引用信息和必要的元数据:
引用字段:media_url 或 media_path
数据类型: VARCHAR 或 TEXT。
存储内容: 存储实际媒体文件在对象存储中的 URL 或 内部路径/文件 ID。
URL 示例: https://your-s3-bucket.s3.amazonaws.com ... f_file.jpg
内部路径/ID 示例: user_uploads/uuid_of_file.jpg。如果存储的是内部路径或 ID,则需要在应用程序层有一个服务负责将其解析为可供客户端下载的完整 URL。
加密: 考虑到 WhatsApp 的端到端加密,即使是 URL,也可能需要进行签名或使用某种访问令牌来确保只有被授权的客户端才能下载文件。实际文件内容本身在上传前就已经被发送方加密。
元数据字段:media_metadata (JSON/JSONB)
数据类型: JSONB (推荐,因为支持索引和高效查询) 或 TEXT (存储 JSON 字符串)。
存储内容: 包含与媒体文件相关的非敏感信息,这些信息通常不需要加密,或是在客户端解密后用于显示:
file_size: 文件大小(字节),用于显示下载进度或流量消耗。
mime_type: 文件类型(如 image/jpeg, video/mp4),用于客户端正确解析。
duration: 视频或音频的时长。
dimensions: 图片或视频的分辨率(宽度x高度)。
thumbnail_url: 缩略图的 URL。缩略图是原始媒体文件的小尺寸版本,通常也单独存储在对象存储中。客户端可以先下载缩略图进行预览,避免立即下载大文件。
caption: 用户为媒体文件添加的文字描述或配文。
encryption_key: 用于解密媒体文件内容的密钥。这个密钥通常是随机生成的,由发送方用于加密媒体内容,并作为消息的一部分(可能与加密内容一起)传输给接收方。服务器只传输这个密钥,不存储或访问其内容。
file_hash: 文件内容的哈希值,用于完整性校验或重复文件去重。
3. 工作流程简述
发送方上传: 用户在 WhatsApp 发送图片/视频。客户端先对媒体文件进行加密和压缩,然后将其直接上传到对象存储服务。
获取引用: 对象存储服务返回一个唯一的 URL 或文件 ID。
消息构建与发送: 客户端构建一条包含 media_url、media_metadata(包括加密密钥和缩略图 URL)以及其他消息元数据的消息,然后将整个消息进行端到端加密。
服务器存储消息元数据: WhatsApp 消息服务器接收到加密后的消息,将其中的元数据(包括加密后的 media_url 或其他引用信息)存储到 Messages 数据库中。服务器不存储媒体文件本身。
接收方下载: 接收方设备收到加密消息,解密后获取 media_url 和 encryption_key。客户端首先显示 thumbnail_url 对应的缩略图。当用户点击查看时,客户端使用 media_url 从对象存储服务下载加密的媒体文件,并使用 encryption_key 在本地进行解密。
这种分离存储的架构是处理大规模媒体内容的业界标准,它将大文件存储和传输的职责从核心数据库中分离出来,从而实现了高效的伸缩性、高性能和低成本。
媒体文件是否直接存储在数据库中?如果不是,如何引用?
-
- Posts: 243
- Joined: Sat Dec 28, 2024 5:47 am