5 分钟
常见数据缓存、存储、分发方案
血缘关系
列表
- MySql
- Redis
- kafka
- HDFS
- OpenTSDB
- Hive
- HBase
- BigTable
- GFS
- TFS
- TiDB
- Haystack
- Dynamo
- Tair
- Elasticsearch
- Zookeeper
- LevelDB
- SSDB
- RocksDB
- 图数据库
MySQL
简介
国内使用最多的RDBMS(关系型数据库管理系统),在互联网领域使用最多。
特点
- 设计上为单机存储
- 单机存储在千万条数量级
扩展方式
- 高可用——主备(不同步),部署多台服务器,一主多备,主备之间共享同一块网络磁盘
- 高可用——主备同步,部署多台服务器,一主多备,主备之间进行通过binlog进行同步
- 异步同步:主库写入成功后事务成功
- 半同步:一个备写入成功后事务成功
- 全同步:所有备写入成功后事务成功
- 分库分表
- 垂直切分:一个表按照列分为多个库表
- 水平切分:一个表按照主键根据一定规则分到多个库表
- 带来的问题:
- 事务支持需要借助外部中间件:xts
- 多库结果合并(group by order by)
- 跨库Join:基础字段冗余法/公共JoinKey
- 容量和增长估算不准确,来回拆库迁移
以上功能一般通过 MySQL中间件实现
- MYSQL proxy (官方)
- Cobar (阿里)
- MyCAT
- TDDL (淘宝)
- DBProxy (美团)
使用场景
- 大多数场景,优先考虑
块存储
简介
传统意义上的块存储就是一个格式化后的磁盘,可以通过mount挂载在操作系统中。随着云的发展,块存储一般以网络磁盘的方式提供。
特点
提供磁盘设备级别存储
主流方案
- 使用Ceph提供的RBD
- Ceph底层提供分布式和高可用
使用场景
- 虚拟机/容器外挂的虚拟存盘
- 注意点
- 不能多点以写方式挂载同一个
- 网络抖动带来IO问题
分布式文件系统
简介
文件系统系统类似于块存储,区别在于:多个客户端可以挂载同一个文件系统,从而实现共享。
特点
- 需要支持Posix协议,做到对应用程序透明
- 支持共享
- 存在问题
- 目录锁性能问题
主流方案
- CephFS
- NFS (企业级较少)
适用场景
- 一写多读(写会加读写锁,多写会存在性能问题)
- 小文件较多
- POSIX文件接口访问
- AI训练
- 共享式外部文件资源依赖
- 注意点
- 单文件系统文件总数 小于 5 亿
- 避免多人写同一文件
- 目录权限,避免误删
- 避免大目录list
对象存储
简介
类似于文件系统的存储,不支持多级任意级别目录树,仅支持二级结构(/存储桶/对象
)
特点
- 扩展性极强,伸缩性强
- 高可靠,高可用
- EB级别存储的数据治理服务
主流方案
- Swifi (OpenStack)
- RGW (Ceph)
使用场景
- HTTP REST访问
- 高并发
- 不需要层次结构
- 相对稳定不变的非结构化数据
- 视频、图片、文档、备份包
- 注意点
- 不适合频繁增删改场景
- 延时敏感不适合
- 不支持目录层次结构、Rename (Rename可以做事务)
缓存
简介
通过将某些数据缓存在内存中,提高响应速度,减少DB压力。
主流方案
- Redis
Redis 注意点:
- 可靠性问题:不能用作持久化存储
- 一致性:最终一致性
- 持久化:可能丢失1s以上数据
- 总容量:1TB以下
- 避免大key(Redis单线程)
- string value < 10kb
- hash/set/zset 元素 < 5000
Redis 方案
- 主从方案(主从同步)
- 集群方案(Sharding,分片存储)
- proxy方案(利用代理屏蔽)
适用场景
- 用户信息缓存 (Redis Hash类型)
- 技术服务后端
- 排行榜 (Redis SortedSet)
- 共享session服务
- 分布式锁
- 关系网络 (Set)
- 最新列表 (List)
- 通知触发器
大规模KV存储
简介
这里的KV存储指的大规模分布式的KV存储。可以作为分布式数据库的底层存储使用。一般情况下Key
是有序的(这样才支持range查询)
常见实现
- Hbase
- RocksDB
注意点
- 单分区HA切换时间秒级,注意重试超时
- 总容量:1TB~1PB
- 提供准确TPS,Latency,Value size以便shard,避免分裂抖动
- 避免大Key (小于 1mb)
文档数据库
简介
提供和RDMS想类似的功能。但是不需要预先定义schema
常见实现
- MongoDB
MongoDB使用注意点
- 不适合复杂联合查询(Join)
- 不适合跨文档事务的场合
使用场景
- Schema Free:文本数据,爬虫数据,嵌套数据
- 高度变化的数据:游戏用户数据
- LBS数据
- 快速迭代开发
分布式数据库
简介
趋向于实现完整的RDBMS的全部功能(比如全部的事务支持、强一致性等)。同时具有分布式存储系统的优点:可扩展,高并发,大规模。
一般情况下底层构建在分布式KV存储之上
常见实现
- Google Spanner (非开源)
- TiDB
- CockroachDB
特性
- 机房容灾
- 面向在线业务
- 分布式事务
- 强一致性(raft等)
- 顺序扫描
- 高可用(多副本)
- 条件更新(cas)
- 数据自动过期(TTL)
- 毫秒级延迟
- TB级大容量
- 百万QPS/TPS
使用场景
- 单行数据不宜过大
- 索引会影响插入效率
图存储(图数据库)
简介
主要用于存储复杂多维关系(比如社交关系),主要存储边(关系)和节点。
主流实现
- Neo4J
当然可以通过分布式KV系统实现
- 点(vertex)
id-type
- 边(Edge)
id1-edgetype-id2-timestamp
注意点
- 可能出现大点(边超级多的点)
- 多维查询,度不能太大
- 热点写入或查询问题
使用场景
- 社交关系(点赞、2度好友关系、共同关注)
- 知识图谱/血缘关系
- 金融气爪风控监测
- 实时引擎推荐
消息队列
简介
用于实现生产者消费者模型的中间存储
主流实现
- RocketMQ
- 有序性
- 事务性
- 延时发送
- 吞吐量较低
- NSQ
- 高吞吐量
- 不保证有序性
- 不持久化
- Kafka
- 吞吐量高于RocketMQ一个数量级
- 分区多了性能会受影响(磁盘随机IO变多)
适用场景
- 解耦生产处理
- 兜底,失败重试
- 弹性,缓冲
- 异步,批量处理
- 跨组织跨部门处理
消息队列的消费语义和投递语义
消费语义
- 消息至多被消费一次 (At Most Once)
- 消息至少被消费一次 (At Least Once)
- 消息仅被消费一次 (Exactly Once)
投递语义
- 如何保证消息最多投递一次
- 如何保证消息至少投递一次
- 如何保证消息恰好投递一次