分布式环境下,提供服务(存储或者RPC等)的集群通常需要有一个(可以是多台)Master角色的机器,来帮助Client端与集群内真正提供服务的机器(以下称为Slave)进行交互。
Master通常需要知道集群内所有Slave的信息(包括机器健康状况,服务信息等),暂且将这些信息称为Metadata,Slave通常是通过心跳的方式将Metadata给到Master。
Master会通过Metadata来帮助Client选择Slave进行服务,下面我们来讨论两种设计方案:
HDFS
HDFS采用的方式是,Client每次都先问下Master(也就是NameNode)我需要去找哪个DataNode。这种情况下Master的单点问题就显得比较严重。
Tair
Tair采用的方式是,Client在启动的时候就从Master那里将Metadata拉到本地,后续就不再每次都先去问Master,这样可以避免Master的单点问题。但是这样又引来了一个新的问题,Metadata信息过期,也就是集群有变化(机器挂掉或者扩容之类的),这时候怎么样去更新缓存的Metadata(缓存的通病 :)。
Tair使用了一个很巧妙的设计,就是给Metadata加上了版本号。每次Metadata有变化,Master就会更新版本号,并将最新的版本号同步到所有Slave上。Slave会在每次给Client的服务响应里将版本号同时返回,Client收到版本号后,会与自己缓存的Metadata的版本号做对比。如果发现自己的版本号不是最新的,那就主动再去找Master把Metadata拉回到本地更新,问题完美解决。