大数据服务架构设计与实践
设计大数据服务架构,是要解决一个问题: 如何基于有限的资源,处理(采集、分析、存储、检索)海量、多元的数据。
有如下理论:
- 分布式理论 —— 提供高效、可靠、可伸缩的计算和存储资源
- 大数据处理理论 —— 提供处理(采集、分析、存储、检索)海量、多元数据的高效解决方案
参考:
分布式系统理论
分布式面临的问题(物理局限性)
基于分布式系统(distributed system)搭建的服务可以提供高效、可靠、可伸缩的特性,但需要考虑这些问题:
- 通信延迟 —— 节点处于不同的物理或逻辑地点,节点上各自保存的数据即便有同步机制,页无法保证节点间保存的数据是实时一致的
- 三种响应状态 —— 节点间通信必然有三种结果,即成功、失败、超时(可能由于节点故障或通信延迟),需要合理处理这三种状态
- 网络分区 —— 可能由于网线被挖断,AB两地区域无法通信,其中的节点会形成可通信的大小两个网络区域,需要合理处理这种情况
分布式要解决的问题(核心痛点)
- 分布式ID(Distributed ID) —— 希望得到一个全局唯一的ID。在分布式系统中需要权衡有序性(号段模式自增、雪花算法)和生成效率(UUID)。 ( link_解决方案整理 )
- 分布式锁(Distributed Lock) —— 希望在多节点并发环境下,实现共享资源的互斥访问。在分布式系统中需要权衡安全性(CP方案:etcd/zookeeper的强一致锁)和执行效率(AP方案:redis的高性能锁)。 (实践中一般选择后者,因为能兼顾性能和99.999999...%的情况,剩下的情况加个乐观锁和重试机制也能解决) ( link_解决方案 / link_解决方案_2 )
- 分布式事务场景(Distributed Transaction)
- 纵向:跨服务协同(Coordination)问题,即“事务原子性” —— 一个业务操作涉及前后多个微服务调用(如下单操作会经过订单微服务、库存微服务),如何保证多级调用的微服务不掉一致,要么一起成功提交、要么一起失败d回滚?
- 解决方案:原子提交协议(Atomic Commit Protocol)
- XA模式(eXtended Architecture/刚性事务/2PC) —— Seata(XA模式) (这算法有巨大性能问题,仅在思想实验或有沉重技术债务的初期分布式系统中使用)
3PC(这算法依然没法解决数据不一致的致命问题,同时还增加了算法的复杂度,所以只在思想实验上有使用)- TODO Saga 模式(柔性事务 / 长事务)
- TODO TCC模式 —— Controller层面控制
- TODO Seate的AT模式(Automatic Transaction)
- TODO 空回滚、幂等、悬挂等问题
- 解决方案:原子提交协议(Atomic Commit Protocol)
- 横向:数据复制(Replication)问题,即“状态一致性” —— 一个微服务存在多个实例,一个实例的状态变化如何一致同步到其他实例上?
- 解决方案:CAP理论和BASE思想
- 纵向:跨服务协同(Coordination)问题,即“事务原子性” —— 一个业务操作涉及前后多个微服务调用(如下单操作会经过订单微服务、库存微服务),如何保证多级调用的微服务不掉一致,要么一起成功提交、要么一起失败d回滚?
数据复制,一致性问题
CAP猜想、BASE思想
基于上述问题,埃里克·布鲁尔(Eric Brewer)在2000年的学术会议 ACM PODC(分布式计算原理研讨会) 上发表了题为《构建鲁棒的分散式系统(Towards Robust Distributed Systems)》的经典主题演讲,演讲阐述了他基于自己研发搜索引擎和分布式缓存的工程经验,指出传统的数据库过度依赖追求绝对完美的ACID强事务特性,这在海量数据和互联网规模下是无法扩展的。同时,他首次系统性地抛出了两个改变行业的想法:(这想法后续被其他人完善,下面列举完善后的版本)
CAP猜想(Brewer's Conjecture): 在分布式网络中,一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)三者不可兼得,系统设计必须进行权衡和取舍。
- C(Consistency,一致性/Linearizability,线性一致性/Atomic Consistency,原子一致性) —— 不管节点间数据如何同步数据,客户端要求读到的数据“永远”是最新的
- A(Availability,可用性) —— 不管多少个节点“不可访问”,客户端要求接口请求永远被响应
- P(Partition tolerance,分区容忍性) —— 不管网络分区是否出现或恢复,要求分布式系统都能“正常”运转 (这里的“正常”指系统的正常,而非要求服务的正常)
由于网络分区是无法避免的,不能一旦出现网络分区就重建集群,这在工程上不可取。 同时,由于网络分区的存在,一致性和可用性无法同时并存:
- 如果满足可用性,那么当网络分区,则一致性无法满足,因为无法让一个分区的数据修改同步到另外一个分区上
- 如果满足一致性,那么当网络分区,则可用性无法满足,因为此时必须阻止读、写才能保证一致性
BASE思想: 这是对传统数据库ACID(原子性、一致性、隔离性、持久性)思想的妥协,是现代大规模分布式系统的底层哲学。 这是基于CAP猜想提出的工程方法论,其核心思想是“既是无法做到强一致性(Strong Consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual Consistency)
- BA(Basically Available,基本可用) —— 当分布式系统出现不可预知的故障时,允许损失部分可用性,但要保证核心可用。 站在更高维度考虑“可用性”问题: 可用性不是0或1的问题,而是核心服务是什么的问题。 如服务高峰,与其让100%的用户都因为系统卡死而无法打开页面,不如让100%的用户都能顺利下单,但其中50%的非核心功能(如看大图)暂时不可用。
- S(Soft State,软状态) —— 指允许系统中的数据存在中间状态,并认为该中间状态不影响系统的整体可用性。
- E(Eventually Consistent,最终一致性) —— 系统不需要实时保证强一致性,但数据在经过一段时间的同步后,最终会达到一致的状态。
笑话:ACID(酸)和 BASE(碱)是完全相反、互相中和的物质。
不同的一致性要求
不同实际业务场景对“分布式一致性(Distributed Consensus)”需求不一样,具体区分有如下三种:
- 强一致性(Strong Consistency) —— 写完立马读到更新后的值。
- 场景:强调数据一致,即C(Consistency,一致性)和P(Partition tolerance,分区容忍性)。但无法保证A(Availability,可用性),如典型的raft算法中当可用且互通的节点小于半数则集群不可用。
- 电商库存、金融交易、医疗记录场景,如银行转账时必须等待所有节点实时余额一致才能确认交易,否则业务系统会重试或报错挂起等待人工干预。 (这种场景的实际运行上一般会有“对账”行为,但这种行为是指两个“业务不互通”系统间的三方干预行为,所以并不意味着单个分布式系统的数据不一致,不是一个概念)
- 共识算法:
主从同步复制,写入需所有节点确认,任何节点失败/响应超时都会阻塞重试 —— MySQL(效率极低)- paxos —— 核心思想是三阶段投票(Prepare -> Accept -> Learn)。过于复杂,导致落地版本都是它的简化版,如raft、zab
- raft —— etcd、consul、TiKV、RethinkDB
- ZAB(Zookeeper Atomic Broadcast,Zookeeper原子广播) —— zookeeper
- kraft —— kafka
- Multi-raft
Redlock —— Redis Sentinel(哨兵模式)(有争议的强一致性:极度依赖系统时钟,如果时钟跳变无法保证100%强一致)
- 场景:强调数据一致,即C(Consistency,一致性)和P(Partition tolerance,分区容忍性)。但无法保证A(Availability,可用性),如典型的raft算法中当可用且互通的节点小于半数则集群不可用。
- 弱一致性(Weak Consistency) —— 写完之后不要求任何时间(能在其他节点)读到更新后的值。也即是说,甚至允许某些节点永远无法督导更新后的值。
- 场景:强调系统稳定,即A(Availability,可用性)和P(Partition tolerance,分区容忍性),同时能保证一定程度的C(Consistency,一致性)
- 高性能采样监测:如每秒采集一万次的传感器数据,偶尔丢几个点不影响整体趋势分析
- CDN缓存
- 共识算法:
- 本地缓存策略:如客户端本地缓存,完全不与服务器校验。
- 场景:强调系统稳定,即A(Availability,可用性)和P(Partition tolerance,分区容忍性),同时能保证一定程度的C(Consistency,一致性)
- 最终一致性(Eventual Consistency) —— 这是弱一致性的子集,添加了“数据最终会一致”约束。即写完之后的一段时间内才能读到更新后的值。
- 场景:
- NoSQL(Not Only SQL,非关系型数据库)场景 —— 这种场景需要高并发写入/海量数据存储/低延迟响应,因而向“强一致性”妥协,选择“最终一致性”或“弱一致性”,然后使用主动同步、超时时间(timeout)、TTL(生存时间/过期时间)等手段使数据更新
- 键值存储场景(Key-Value Store) —— 解决基于唯一的KEY进行数据快速读写问题。
- 业务:
- 用户Token/状态缓存:存储用户的登录 Session、鉴权 Token。
- 高频计数器:微博的实时热搜点赞数、直播间的在线观看人数、视频播放量。
- 技术:redis、Memcached
- 业务:
- 列族/宽列存储场景(Wide-Column/Column-Family Store) —— 解决海量数据(PB级)的大规模并行读写、水平扩展问题。
- 业务:
- 大数据日志/追踪:系统监控日志、APM 链路追踪数据(SkyWalking存储)。
- 物联网(IoT)传感器数据:智能电表、车联网每秒上传的车速、油耗、温度等时序轨迹数据。
- 社交时间线(Feed流):微信朋友圈、微博的动态流,拉取好友的最新发布列表。
- 技术:Cassandra、HBase、ClickHouse/InfluxDB (💡这里HBase、ClickHouse特别在于其元数据维护都是“强一致”的,但都通过各自手段使性能达标)
- 业务:
- 文档存储场景(Document Store) —— 提供数据以类似JSON/BSON的半结构化文档格式的存储和查询。相比于“全文检索场景”,这里强调支持频繁、复杂的修改和严格的事务(ACID)支持。
- 业务:
- 电商商品详情页:一件商品有不同的属性(衣服有颜色尺寸、手机有内存屏幕),用文档存储可以随时增加字段。
- 内容管理系统(CMS):博客文章、评论系统、游戏玩家的个人装备与属性面板。
- 技术:MongoDB
- 业务:
- 全文检索场景(Search Engine / Inverted Index) —— 简称搜索引擎。相比于“文档存储场景”,这里强调多维度、模糊的查询
- 业务:
- 电商多维商品搜索:根据品牌、价格区间、颜色、销量、好评率等十几类条件组合筛选商品。
- ELK 日志分析平台:安全审计、全量系统日志的高效检索。
- 技术:ElasticSearch(ES)、Solr、OpenSearch/elasticsearch-oss
- 业务:
- 键值存储场景(Key-Value Store) —— 解决基于唯一的KEY进行数据快速读写问题。
- 分布式对象存储,如AWS S3或阿里云OSS,上传一张照片后立刻访问可能404,但几百毫秒后就能访问。
- DNS(域名系统),你修改了 IP,全球各级 DNS 服务器逐步同步,最终全球一致。
- NoSQL(Not Only SQL,非关系型数据库)场景 —— 这种场景需要高并发写入/海量数据存储/低延迟响应,因而向“强一致性”妥协,选择“最终一致性”或“弱一致性”,然后使用主动同步、超时时间(timeout)、TTL(生存时间/过期时间)等手段使数据更新
- 共识算法:
- Gossip —— Redis Cluster(主从架构)通过该算法实现状态节点发现。 (注意:redis的数据同步还只是简单的异步复制)
Zen Discovery —— Elasticsearch(7.0之前)的自研算法,容易脑裂- Cluster State Coordination —— Elasticsearch(7.x 及以后)的算法(借鉴了raft思想,理论上可以强一致,但是他从性能考虑,只是把数据写到log里,通过refresh机制落盘后才可读,所以还是归类为仅保证最终一致)
- Peer-to-Peer(异步同步) —— eureka
- Gossip 协议 + NRW 机制 —— Cassandra
- CRDT(Conflict-Free Replicated Data Types) —— 社交平台:如点赞、评论、动态等操作,可以容忍一定的延迟和不一致;分布式缓存:如用户会话、商品库存等,能够容忍短期的不一致
- CRDT(无冲突复制数据类型) —— 分布式聊天软件、协同文本编辑器(如 Notion 协同)
- 场景:
微服务管理:
- Spring Cloud
- ServiceComb 微服务快速搭建框架 | 国产化 Spring Cloud
注册中心:
- zookeeper
- nacos
- consul
- etcd
- eureka
大数据处理理论
todo hadoop todo hdfs todo yarn todo hive todo spark todo hbase