目录
数据存储历史背景:
数据存储的方式:
全量备份raid1:
数据切片raid0:
数据冗余raid5:
数据一致性:
强一致性:
弱一致性:
顺序一致性:
最终一致性:
子分类-因果一致性:
子分类-“读己之所写”一致性:
子分类-会话一致性:
子分类-单调一致性:
子分类-单调写一致性:
CAP原则:
Paxos原理:
有主模型:
无主模型:
Zookeeper的角色分配:
Follower:
Observer:
提议(Proposal)--ZNode Change:
提议编号(PID)--Zxid:
正式法令--所有ZNode以及其数据:
选取Leader的条件:
ZK Server的四种工作状态:
操作Zookeeper:
节点的分类:
ZKServer的监听机制:
官方说明:
机制特点:
数据监视:
父节点Watcher事件类型:
子节点Watcher事件类型:
ZK ACL权限控制:
zk的节点共有5种操作权限:
身份认证的4种方式:
权限:
额外补充点:
Zookeeper用作队列管理例如文件系统、通知机制时:
所有的计算任务都由一台计算机完成,数据的存储也有一台计算机完成。这样的单节点计算照成了单点故障、性能瓶颈等问题。
它有效缓解了IO问题,但是不利于数据的扩充,磁盘的利用率只有50%。
有效缓解了IO问题,还可以更多的去存放数据,容量也可以扩充,但是如果其中一个节点异常,所有数据都失效。磁盘的利用率为100%。
RAID的基本思想是将多个容量较小、相对廉价的磁盘进行有机组合,从而以较低的成本或得与昂贵大容量磁盘相当的容量、性能、可靠性。
存放的数据会进行奇偶校验,如果损坏了一块盘,当盘重新挂载后,会自动恢复丢失的数据。这种模式磁盘最多只能损坏一块。磁盘的利用率为n-1/n。
所有的读写操作都按照全局时钟下的顺序执行,且任何时刻线程读取到的缓存数据都是一样的。加入更新一次数据,所有的存储节点都要更新数据。而且必须等待所有的节点更新完成后才能继续进行读写操作。
写入数据时当前节点不能被读取,相当于java中的线程加锁。
不能保证任何一次读取都能督导最近一次写入的数据,但能保证最终可以读到写入的数据。
读取数据的时候,不需要是最新的,只要能够读到就行。
多个线程的整体执行可能是无序的,但是对于单个线程而言,要保证任何一此都都能读到最近一次写入的数据,任何一次读都能读取到某个数据最近一次写的数据。
系统所有的进程的顺序一致,而且是合理的,即不需要和全局始终下的顺序一致,错的话一起错,对的话一起对。下一图是无序,下二图是顺序。
从客户端来看,一致性主要指的是多并发访问时同时更新过的数据如何获取的问题。我们有可能暂时获取不到最新的,但是我们最终还是能访问到最新的。
从服务端来看,则是更新如何复制分布到整个系统,以保证数据最终一致。
我们只需要半数以上的用户拿到正确数据即可,集群认为半数以上的机器存储成功就成功。所以集群搭建最好选择奇数。
如果进程A通知进程B它已经更新了一个数据项,那么进程B的后续访问将返回更新后的值,且一次写入将保证取代前一次写入。与进程A无因果关系的进程C的访问遵循最终一致性规则。例如查询微博和评论。
当进程A自己更新一个数据项后,它总是访问更新过i的值,绝不会看到旧值,这时因果一致性模型的一个特例。
都自己的数据都从主服务器去读,读别人的是数据都从从服务器去取。
这个是上一个模型的使用版本,它把访问存储系统的进程放到会话的上下文中,只要会话还存在,系统就保证“读己之所写”一致性。如果由于某些失败情形令会话终止,就要建立新的会话,而且系统的保证不会延续到新的会话。确保会话内访问的都是最新的。
如果进程已经看到过数据对象的某个值,那么任何后续都不会访问在那个值之前的值,不会读取最旧的数据。
系统保证来自同一个进程写操作的顺序执行,要是系统不能保证这种成都的一致性,就非常难编程了。
是一种鱼和熊掌不可兼得的问题,CAP原则是指在一个分布式系统中,一致性、可用性、分区容忍性这三个要素只能同时实现两点,不可能三者兼顾。
一致性:
每次读取都会收到最新的写入或者错误。
可用性:
在一个固定时间点段内,每个请求都会收到一个不是错误的响应,一般都是一台机器。
分区容忍性:
节点之间的网络丢弃(或延迟)了任意数量的消息,系统仍继续运行,数据有一定的备份。
用于解决一致性问题的算法,有多个节点就会存在节点间通信的问题,存在两种节点通讯模型:共享内存(shared memory)、消息传递(Messages passing),它是一个基于消息传递的一致性算法,它被认为是目前位置唯一的分布式一致性算法,其他算法都是Paxos的改进或简化。
它进行的是数据的全量备份,使用的是弱一致性、最终一致性,是无主模型。
是有主模型。
只能有一个主发送指令、提议。单主会单点故障,如果出现多个主就会脑裂。
人人都能发送指令、投票,投票人数有可能导致分区(分不同的阵营),事务编号混乱,每个节点都有可能有自己的提议,提议的编号不能重复和小于。主要集群节点数目高于1/2 + 1,集群就可以正常运行。
拥有选举和投票权。处理客户端的非事务请求,转发事务请求给 Leader。
同Follower,只可以为客户端提供数据的查询和访问,如果客户端执行写请求,只是将请求转发给了Leader。它可以在不影响集群事务处理能力的基础上提升集群的非事务处理能力。
它不参与任何形式的选举和投票。
客户端的提议会被封装成一个节点挂载到ZK维护的目录树上,我们可以对数据进行访问(绝对路径),数据量不能超过1M。
全局递增的事务ID,会按照数字序列递增,不会减少不会重复,所有的Proposal(提议)都在被提出的时候加上了zxid。
Zxid是一个 64位的数字,高32位是epoch(纪元、时代、时期、世(地质年代,纪下分世))用来标识 Leader周期,如果有新的Leader 产生出来,epoch会自增。低 32 位用来递增计数。当新产生 Proposal,会依据数据库的两阶段过程,首先向其他的Server发出事务执行请求,如果超过半数的机器都能执行并且能够成功,那么就会开始执行。
超过半数的服务器将数据更新更新这个数据,就说明这个数据已经是正式的了。
首先按照事务zxid进行排序,如果事务zxid相同就按照myid排序。
服务器四种状态分别是 LOOKING、FOLLOWING、LEADING、OBSERVING。
LOOKING:寻 找Leader状态。当服务器处于该状态时,它会认为当前集群中没有Leader,因此需要进 Leader选举状态。
FOLLOWING:跟随者状态。表明当前服务器角色是Follower。
LEADING:领导者状态。表明当前服务器角色是Leader。
OBSERVING:观察者状态。表明当前服务器角色是Observer。
以KeyValue的方式存在,以树状结构管理数据,及时目录还是数据的key。所有的数据访问都必须以绝对路径的方式呈现。
查看元数据信息,get /...
cZxid 创建这个节点的事务id
ctime 创建时间
mZxid 最后 一次修改节点数据的事务ID
mtime 修改时间
pZxid 子节点的最新事务ID
cversion 对此znode的子节点进行的更改次数
dataVersion 对此znode的数据所作的修改次数
aclVersion 对此znode的acl更改次数
ephemeralOwner=0x0(持久化节点)0x16ee...(临时节点)
dataLength 数据的长度
numChildren 子节点的数目
临时节点:create -e 只要创建节点的会话有效,节点就不会失效,可以被所有的客户端所查看。
持久化节点:默认创建的就是持久化节点。
序列化节点:create -s 会自动在名字后面添加一个有序的序列号。为了防止创建节点时,有重名的而导致创建失败,它又可以分为临时序列化和持久化序列化节点。
一个Watch事件是一次性的触发器,当被设置了Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了Watch的客户端,以便通知它们。
一次性触发数据改变发生时,一个watcher event会被发送到client,但是client只会收到一次这样的信息,watcher event是异步发送的。
zk有数据监视和子数据监视,getdata() and exists()设置数据监视,getchildren()设置子节点监视。
watch监听有不同的类型,有监听状态的stat,内容的get,目录结构的ls
创建父节点触发:NodeCreated
修改父节点数据触发:NodeDataChanged
删除父节点触发:NodeDeleted
使用ls命令为父节点设置watcher,子节点被创建时触发NodeChildrenChanged
使用ls命令为父节点设置watcher,子节点被删除时触发NodeChildrenChanged
使用ls命令为父节点设置watcher,子节点被修改时,不触发事件
create、read、write、delete、admin,也就是增、删、改、查、管理权限,这5种权限简写为crwda,这5种权限中,delete是指对子节点的删除权限,其他4种权限指对自身节点的操作权限。
world:默认方式,相当于全世界都能访问。
auth:代表已经认证通过的用户(cli种可以通过iaddauth digest user:pwd 来添加当前上下文中的授权用户)。
digest:即用户名:密码这种方式认证,也是业务系统中最常用的。
ip:使用IP地址进行认证。
schema:
world:只有一个用户anyone,代表所有人(默认)
ip:使用IP地址认证
auth:使用已经添加了认证的用户认证
digest:使用用户名密码的方式认证
id:
world:只有一个id,anyone
ip:通常时一个IP地址或者地址段
auth:用户名
digest:自定义
create简写为c,可以创建子节点
delete简写为d,可以删除子节点
read简写为r,可以读取节点数据以及显示子节点列表
write简写为w,可以设置节点数据
admin简写为a,可以设置管理权限
查看ACL:getAcl /test
设置ACL:setAcl /test world:anyone:wa
添加用户:addauth digest zhangsan:123456
设置权限:setAcl /test auth:zhangsan:123456:rdwca
①同步队列,当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。
②队列按照 FIFO 方式进行入队和出队操作。
解释:
①是在约定目录下创建临时目录节点,监听节点数目是否是我们要求的数目。
②和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。在特定的目录下创建 PERSISTENT_SEQUENTIAL 节点,创建成功时Watcher通知等待的队列,队列删除序列号最小的节点用以消费。此场景下Zookeeper 的 znode 用于消息存储,znode 存储的数据就是消息队列中的消息内容,SEQUENTIAL 序列号就是消息的编号,按序取出即可。由于创建的节点是持久化的,所以不必担心队列消息的丢失问题。