分布式系统理论
1、 CAP: 分布式系统只能满足其中两个
- Consistency :一致性
- Availibility:可用性
- Partitions Tolerance :分区容错性
C,A : SQL 传统的数据库。 两段机制。
C,P :悲观枷锁机制,分布式加锁机制。加锁机制与SQL不太一样。 这里的C为最终一致性。 放弃C后的特例,既可以保证可用性,也可以保证最终一致性。
A,P : 只保证分区容错和可用性,例如 DNS
2、数据一致性:
2.1 强一致性,无论在哪个节点上修改,其他节点必须马上看到
2.2 弱一致性:存在某一个不一致状态的时间段。 存在不一致性窗口。有可能两个节点始终不一致
2.3 最终一致:弱一致性的特例,可以略过中间态直接保证最后状态一致。
2.4 数据一致性的实现技术:
1)Quorum系统NRW策略: 法定票数
R : 为了完成一次读操作最少需要的副本数
W: 为了完成一次写操作最少需要的副本数
N:总共拥有的副本数
强一致性: R + W > N
弱一致性: R + W < = N 最多只能保证最终一致性。
2) 2PC
3)Paxos算法
4) vectors clock(向量时钟)
三、事务 (transaction)
ACID:
A: 原子性: 需要每次事务操作要只有“有” 或“无”两种状态: 如果一部分事务操作失败,那么整个事务操作失败,结果数据库状态保持操作之前的状态不变。原子性系统必须保证在任何情况下(包括断电,程序错误,系统崩溃), 对于外界来看,递交一次事务时不可以拆分的,并且中断的事务时不存在的。
C: 一致性: 一致性保证任何事物都可以将数据库从一个合法状态转换成另一个合法状态。 所有数据库的写入必须符合事先设立的条件,包括约束,级联,触发,或者所有的组合。 这个虽然无法保证程序员编程时都是正确的,但是至少可以保证编程错误不能违背设定好的条件。
I:隔离性: 隔离特性保证同时进行事务操作产生的系统状态结果与序列操作相同。 隔离性的主要目标就是并发控制。由于并发控制,不完整事务将不存在。
D:持久性: 持久性意味着一旦事务递交,将会被保持,即便断电,宕机,错误。 例如在关系性数据库中,一旦一组SQL语句执行以后,结果将会被永久保存(即便数据库在执行后马上被崩溃)。 为了避免断电,事务必须存放在非易失性存储内存中。
BASE:用于对分布式系统的评估
最终弱一致性,可用性优先,采用乐观的方法,适应变化,更简单,更快
NoSQL数据库存储模型
NoSQL数据存储模型
列式模型:
数据模型: 数据案列存储, 将统一列数据存在一起,同一个节点上或者同一个数据集中
优点: 查找迅速, 可扩展性比较强,易于实现分布式
缺点: 功能相对有限
应用场景: 主要用于分布式文件系统或者分布式存储 ,海量数据存储,背后依托分布式文件系统
典型产品: Google bigTable, facebook Cassandra ,hadoop HBase, Hypertable
键值模型(key-value):
应用场景: 内容缓存。用于处理大量并行数据高访问高负载场景
优点:查找迅速
缺点,数据无结构,只能当做字符串和二进制数据。
典型产品: Redis, Dynamo(亚马逊),Riak
文档模型:
数据模型: 与键值模型类似,但是value指向结构化数据,一个键可以多个值。多个键值对附加了一个容器。键值可以嵌套。
优点: 数据格式要求不严格,无需事先定义格式。 所有记录不需要拥有相同的字段,可以单独临时增加。 每一个文档理论上可以不需要和其他文档有任何关系。
缺点: 查询性能不高,比起SQL还是很好的, 缺乏统一查询语法。
应用场景: 主要用于web应用。
典型产品: MongoDB, CounchDB,RethinkDB
图式模型:
数据模型: 图结构模型
优点: 利用图结构相关算法提高性能,满足特殊场景的应用需求。 例如,社交网站的推荐模型
缺点: 难以实现分布式,功能相对定向,只能适用于特定场景。
应用场景: 社交网络,推荐系统,关系图谱
典型产品: Neo4J,Infinite Graph
MongoDB
一、MongoDB相关介绍
- Scalable, high performace, open source, schema free, document no-sql oriented database.
- 适合存储,Humongous( huge + monstrous)
- Document Database : JSON, BSON 存储格式
- Schema free
- High performance
C++: 开发
Full index support : 支持完全索引
No transactions (has atomic operations): 不支持事务
Memory-mapped files (delayed writes) : 操作在内存中完成,而后同步硬盘
- Scalable:
Replication : 复制
Auto-sharding: 分片
- Document-based queries: 支持基于文档的查询, 可以返回一个文档,或者一个游标指向结果集
Flexible document queries expressed in JSON/Javascript : 支持json, javascript的表达式
- Map/Reduce
Flexible aggregation and data processing : 灵活数据聚合
Queries run in parallel on all shards: 在各shard上面并行进行
- 支持GridFS存储文件系统
- Store files of any size easily : 可以用于存储各种大小文件的文件系统 ,海量小文件
- Geospatial Indexing: 支持空间索引
Find object based on location (find closes n items from x )
- Many Production Deployment : 商业化应用还算广泛。
- Dynamic queries : 动态查询
- Query profiling : 支持查询性能剖析
- Replication and fail-over support: 能够复制并且自动完成故障节点转移,通过选举协议自动选举出主节点。
- 特别适用于:
Websites : 高并发,
Caching:通常用redis, Hbase
High volume, low value :海量低价值数据
High Scalibility :
Storage of program objects and json : 始于json对象开放的场景,多为web开发
- 不适用应用:
Highly transactional : 需要使用事务
Ad-hoc business intelligence : 商业决策
Problems requiring SQL : 需要SQL接口
二、MongoDB 数据结构
面向collection的数据库 :
数据库:数据库无需创建
表:在mongodb中为集合(collection), collection中为文档对应传统的行
集合: 集合也无需事先定义
三、安装
这里就不过多介绍
/etc/yum.repos.d/mongodb-org-3.2.repo [mongodb-org-3.2] name=MongoDB Repository baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.2/x86_64/ gpgcheck=0 enabled=1
四、副本集架构
1.master/slave:主从架构,master 负责读写,slave 只能读(不建议使用)
2.复制集架构(replica set)基本概念:
副本及成员:
- 主节点(primary node): 接受读写,操作通过选举产生
- 从节点(second node):保存一个副本
1) 优先级为0的从节点(Priority 0 Replica Set): 存储一个副本,参与选举,但是不能被选举。只能读不能写。
2) 隐藏节点(Hidden Replica): 储存一个副本,参与选举,不能被选举,不能被程序看见,所以不读也不写,只是保存副本用于特定工作,例如做备份等工作。
3) 滞后节点(Delay Replica): 与隐藏节点类似,但是存储的是一个时间段以前的信息,例如1小时以前的信息,用于回滚备份。
3.arbiter 节点: 没有副本只参与投票
副本构架策略:
- 副本数量策略(Deploy an Odd Number of Members):使得选举可以正常进行,如果没有使用arbiter节点
- 考虑添加容错节点(Consider Fault Tolerance): 容错数是指,多少个节点挂掉,其他还能正常选举出主节点的机制。详见官方文档。
- 使用隐藏节(hidden Replica, Delay Replica)点和滞后节点用于特殊功能(backup or reporting)
- 把读取压力很大的需求负载均衡到多个从节点上(Load Balance on Read-Heavy Deployments): 当负载没那么大时候,可以收回
- 在目前节点节点压力没有完全饱和时添加新的节点。 (Add Capacity Ahead Demand)
节点的地理分布(Distribution of Members)
- 要地理分布节点到不同个数据中心,以防某个中心挂掉
- 使得大部分节点集中存放,使得选举不会受到网络影响
- 给操作打标(Target Operations with Tag Set)
启动日志功能,防止意外服务中断。例如断电
副本集的高可用:
- 选举行为(Replica Set Elections):
选举因素:
Heartbeats: 心跳信息
Priority Comparisons: 优先级选择
Optime: 最有时间时间戳,选择拥有最近更新时间戳的节点
Connections: 可以与大部分节点通信的优先
Network Partitions:如果主节点宕机,但是从节点很分散不在同一个数据中心,则有可能从节点全都变成只读模式,所以建议大部分节点放在同一个数据中心中
选举触发条件:
新增节点(initiation of new replica set)
从节点与主节点不能通信
主节点宕机
选举优先权(Vetoes In Elections): 没有选举权(Vetoes)的节点,不可以选举,但可以被选举为主节点。通常副本节点可以最多50个但是,可以选举的只有7个,剩下的不参与选举但是可以被选为主节点
- 副本及崩溃时的回滚机制(Rollbacks During Replica Set Failover:当宕机的主节点恢复时,由于数据和从节点不同步,原主节点回滚回与其它节点相同的状态。 MongoDB会尽量避免回滚,因为回滚意味着丢失原主节点最新写进的操作。
回滚数据的收集: 回滚数据存放在dbPath下面rollback/目录中格式如下
<database>.<collection>.<timestamp>.bson
## 例如
records.accounts.2011-05-09T18-10-04.0.bson
使用: bsondump工具读取回滚数据,使用mongorestore来恢复到新的主节点中。
避免数据回滚:提高 write concern {w:1} 级别来避免回滚,使用 w:majority 来确定,所有数据在第一时间同步到从节点。
回滚限制: 默认不得回滚超过300M以上的数据,如果需要回滚大于300M的数据,则需要人工干预
副本集的读写机制: 对于客户端来说,副本集存在与否是完全为知的。
- 副本集写操作规则(Write Concern for Replica Sets)
默认写规则: 默认写规则只写入主节点
修改默认写规则:
cfg = rs.conf()
cfg.settings = {}
cfg.settings.getLastErrorDefaults = { w: “majority”, wtimeout: 5000 }
rs.reconfig(cfg)
用户也可以通过副本集标签来自定义写规则
- 副本集读偏好规则(Read Preference):
primary: 默认选项,因为主节点存放最新写入的内容
primaryPreferred:大多是情况从主节点读取,如果主节点读取不到则通过从节点读取。
secondary:所有的读操作都可以从从节点读取.
secondaryPreferred:有限使用从节点读取。
nearest:从网络等待时间(latency)最短的节点读取
不建议使用从节点读取来增加读性能,建议使用shard增加读性能。
- 副本集节点的读取挑选机制(Read Preference Process):
读节点选择标准:如果选择读取非主节点的偏好,可供读取成员节点的选择规则(Member Selection)如下
1)列入所有可用成员节点,参考节点成员类型(从节点,主节点,或者所有成员节点)
2)如果使用了标签,则去除标签(tag)不能匹配的节点
3)选择可用节点中绝对距离最近的节点。
4)建立一个ping距离表,选择绝对最近的节点
5)随机选择
申请关联链接(Request Association):节点选择完毕后,申请与节点建立关联关系。由于不同节点之间数据会略有差异,所以读取偏好确定后,就会和某一个节点建立关联,保证读取的数据连续。这个关系在一下三种情况下会被打破。
1) 应用选择另一个节点作为读取偏好
2) 连接断开
3) 客户端收到套接字断开。原因可能是网络故障,服务器连接错误触发重试,这些对于客户端来说都是不可见的。
自动重试:
1) 客户端尽可能长的使用同一连接。
2) 如果连接断开则,使用以后的读节点偏好(read preference modes)连接一个新节点。
3) 如果尝试在同一读写偏好条件下连接三个节点都失败,则返回错误信息。
4) 如果检测到宕机信息,驱动会快速刷新副本集信息。
对于shard集群的读取偏好:
1) 对于shard的副本集,规则和普通副本集类似。
2) 不指定偏好的链接,默认为primary
3)计算距离是从mongos到mongod的举例而不是客户端到mongod的距离。
- 复制过程(Replication Processes)
副本集操作日志(Replica Set Oplog)
1) Oplog Size:根据系统有默认值,但是可以通过oplogSizMB 指定, 64-bit Linux 为5%可用空间。
2) Oplog Status: 通过rs.printReplicationInfo() 查看oplog状态
副本集同步Replica Set Data Synchronization
1) 初始化同步(Initial Sync):同步所有源数据到一个空的副本主机中。
复制整个数据库,执行源数据库的修改,建立所有的索引
2)复制(Replication):初始化同步以后,接连不断的同步后续的操作到副本中。
3) 合法性和持久存储
4) 多线程复制
5) 提前获取索引来提高复制的通量。
副本集配置:
配置参数:
replSet: 副本集名称
oplogSize: 操作日志大小,初始化为磁盘可用空间的5%。第一次初始化后,将以后无法更改。 最好开始指定。
fastsync: 完成快速同步。
replIndexPrefectch:副本索引预取。
选举触发:
一个新节点刚刚上时,不能马上触发选举,过一段时间以后才会触发。
优先级为0的节点,不能触发选举,没有被选举权,只能选举发生时参与选举
七、sharding构架
sharding构架的介绍
- 应用场景:
大数据量,并且高吞吐量数据时
高并发查询,使得单台服务器CPU压力过大
数据量过大,一台服务器无法存放
操作数据量过大,内存压力和I/O压力过大
如果系统已经接近极限时,再使用shard会变得比较困难, 如果在可预见的将来系统将会被使用到极限,则最好尽快使用shard
- sharding三部分:
Shards: 分片存储的数据,为了保证High Availablility 和 data consistency, 每个shard建议被做成副本集
1)Primary Shard : 可以存储没有分片的collection
2)Shard Status: sh.status() 用于查看shard的整体状态
Query Routers: mongos服务, 直接与客户端交互的,代理客户从shard上面读取数据组合后返回给客户端。
1)可以使用一个或多个。
2) 如果使用多个,需要前端负载均衡,或者反向代理。需要配置前端代理保证每一个客户端的链接只能链接同一个mongos
Config servers: 存储集群元(metadata)数据用于把整体数据映射到各shard的中。
1)生产环境中最好使用三个做冗余。并且是单独主机,如果是多组shard集群,则每个集群一组Config Server
- Shard Keys 相关
Range Based Sharding: 范围分区,优点是读取时容易锁定在有限个shard上,但是写入时有可能集中在某一个shard。
Hash Based Sharding: 哈希算法分区,优点是写入分散,缺点是读取时有肯能信息分散在所有shard上,会降低读性能。
Shard keys 不能改变。
选择sharding key 的标准
1) 应该在哪存数据
2) 应该在哪的到希望的数据
- shard 集群的高可用:生产环境下的shard集群是没有单点故障的。
mongos部分: 每个程序可以拥有独立的mongos, 某一个mongos不可用不会影响数据完整。
shard mongod部分:
1) 如果shard mongod 为主节点,则重新选举一个主节点。
2) 如果shard mongod 为从节点,并与主节点断开,但是仍然可以保存所有数据
3) 如果某一个节点毁灭性损坏,另外两个节点依然会保存着所有数据。
shard 副本相关: 如果某个shard副本整个损坏, 则这部分shard数据全部不可以访问。另外的shard还可以访问
Config server相关:
1) 如果一个或两个不可用,则只能读不能做片分离和片移动
2) 如果全部不可用,则不可恢复。
重命名Config server 相关:
1) 如果命名或地址改变。必须重启mongod 和 mongos
2)尽量使用DNS名来避免主机名改变的麻烦。
shard key相关:
1)尽可能确保key可以使得数据分布均匀。
2)可以分摊写压力
3) 可以使mongos把大部分的读操作定位在有限个shard上面。
shard的工作机制
- Shard Collection Balancing:
基本法则
读数据尽可能来自于少的分片,写数据尽可能分离,最差写情况读的时候根本不知道在哪个分片上,全shard扫描
shard key 应该是主键,查询时候经常用到的键。
同时选择分片键时候,尽量避免跨分片查询
分片时候,尽量先垂直切割,避免热区数据。然后再水平切割
chunk 64 默认
分片越小越容易迁移。
rebalance功能可以使得不均衡的分布变得均衡
sharding:新增shard,移除shard
mongo的监控命令:
mongodump
mongorestore
mongoexport
mongoinport
mongodb mapreduce
mongodb GridFS
原创文章,作者:nene,如若转载,请注明出处:http://www.178linux.com/90990