存储图片、视频等媒体消息的实际内容是构建像 WhatsApp 这样消息应用的关键组成部分,因为它涉及到处理海量、大尺寸的二进制数据,对存储系统提出了极高的性能、可扩展性和可靠性要求。核心原则是:不直接将媒体文件存储在关系型数据库中。 相反,数据库只存储指向这些媒体文件的引用(文件路径或 URL),而实际的媒体内容则存储在专门的分布式文件存储系统或对象存储服务中。
以下是 WhatsApp 可能采取的存储策略:
1. 媒体文件的存储位置:分布式文件存储/对象存储
这是最重要的一点。像 WhatsApp 这样的应用,每天处理的图片和视频流量是惊人的,传统的数据库(无论是 SQL 还是 NoSQL)都不适合直接存储这些大文件。
选择方案:
云对象存储服务: 例如 Amazon S3、Google Cloud Storage、Azure Blob Storage。这些服务提供高可用性、高可扩展性、持久性和成本效益,非常适合存储非结构化数据。
自建分布式文件系统: 例如 HDFS (Hadoop Distributed File System)、GlusterFS、Ceph。大型科技公司可能会根据自身需求构建和优化自己的私有存储解决方案。
CDN (Content Delivery Network): 对于经常被访问的媒体文件,可以将其缓存在 CDN 边缘节点,以加快全球用户的下载速度。
工作流程:
上传: 当用户发送图片或视频时,客户端(WhatsApp App)首先会将媒体文件直接上传到上述分布式文件存储系统。
生成引用: 上传成功后,存储系统会返回一个唯一的文件 ID 或 可访问的 URL。
消息元数据存储: 客户端或服务器将这个文件 ID/URL 以及其他媒体元数据(如文件类型、大小、时长、缩略图 URL 等)作为消息的一部分,存储到核心的消息数据库中。
下载: 接收方收到消息后,客户端会从消息元数据中提取文件 ID/URL,然后直接从分布式文件存储系统或 CDN 下载实际的媒体文件。
2. 数据库中的存储方式:元数据与引用
在核心的消息数据库(例如,存储消息文本、发送者、时间戳的表格)中,媒体消息的实际内容不会被存储。相反,我们会存储指向这些内容的引用和相关的元数据。
核心字段: 在 Messages 表中,会有如下字段:
message_id: 消息的唯一 ID。
message_type: 指示消息 比利时 whatsapp 数据库 类型为 IMAGE、VIDEO、AUDIO、DOCUMENT 等。这是关键的区分字段。
media_url 或 media_path:
数据类型:VARCHAR 或 TEXT。
或一个内部路径/文件 ID。如果使用内部路径/ID,则应用程序层需要一个服务来将其解析为可下载的 URL。
重要性: 这是接收方下载媒体文件的“凭证”。
媒体元数据(media_metadata):
为了提供更好的用户体验和更高效的媒体处理,还会存储额外的元数据。这些元数据通常以 JSON 对象的形式存储在 Messages 表的一个 JSONB 或 TEXT 字段中(如果数据库支持 JSON 类型,如 PostgreSQL 的 JSONB 类型会更高效),或者将关键元数据拆分成单独的列。
常见元数据包括:
file_size (整数):媒体文件的大小(以字节为单位),用于显示下载进度或提醒用户流量消耗。
mime_type (字符串):文件的 MIME 类型(如 image/jpeg, video/mp4, audio/aac, application/pdf),用于客户端正确解析和显示文件。
duration (整数):对于视频和音频文件,存储其时长(以秒或毫秒为单位)。
dimensions (字符串或 JSON):对于图片和视频,存储其分辨率(如 "1920x1080" 或 {"width": 1920, "height": 1080}),用于客户端进行布局或缩放。
thumbnail_url (字符串):缩略图的 URL。在用户下载完整媒体文件之前,客户端可以先加载并显示低分辨率的缩略图,提供即时预览,减少带宽消耗。缩略图通常也在对象存储中单独存储。
encryption_key (字符串):媒体文件通常也需要进行端到端加密。这里的 encryption_key 不是指消息本身的加密密钥,而是用于解密媒体文件内容的密钥。这个密钥通常是随机生成的,并随消息的加密内容一同传输,确保只有接收方才能解密并访问媒体内容。
file_hash (字符串):文件的哈希值(如 SHA256),用于去重(deduplication)。如果两个用户发送了完全相同的文件,可以只存储一份实际文件,并让多个消息引用它,节省存储空间和带宽。同时,也可以用于文件完整性校验。
caption (字符串):图片或视频的文字描述/配文。
3. 端到端加密的考虑
WhatsApp 的一个核心安全特性是端到端加密,这同样适用于媒体文件:
媒体文件在发送方设备上进行加密,然后才上传到对象存储。
数据库中存储的 media_url 指向的是加密后的文件。
解密密钥作为消息元数据的一部分(通常是随消息的加密内容一起传输,并通过 Signal 协议协商),只有接收方才能访问和解密。
WhatsApp 服务器无法直接访问媒体文件的明文内容。
4. 流程总结
发送方:
用户选择图片/视频。
客户端对媒体文件进行压缩、加密。
客户端将加密后的媒体文件上传到对象存储服务。
对象存储返回一个文件 ID/URL。
客户端构建包含 message_type、media_url 和 media_metadata(包括加密密钥、缩略图 URL 等)的消息,对整个消息再次进行端到端加密。
加密后的消息发送到 WhatsApp 消息服务器。
WhatsApp 服务器:
接收加密后的消息,将其路由到接收方。
如果接收方离线,临时存储加密后的消息(包括媒体元数据)。
不解密也不存储媒体文件本身。
接收方:
设备收到加密消息,进行解密。
解析 message_type 为媒体类型。
显示 media_metadata 中的 thumbnail_url 对应的缩略图。
当用户点击下载时,客户端使用 media_url 和从消息中获取的解密密钥,从对象存储服务下载并解密媒体文件。
这种分离存储的架构是处理大规模媒体内容的核心策略,它将文件存储的职责从核心数据库中分离出来,从而实现了高效的伸缩性和可靠性。
如何存储图片、视频等媒体消息的实际内容(文件路径/URL)?
-
- Posts: 243
- Joined: Sat Dec 28, 2024 5:47 am