接连上篇。
上篇文章中,你可以清晰的了解到Sentry的组合拳(一堆plugins)是如何打通Hive和HDFS端的权限,并做统一管理的。正向信息流是完整的,那逆向的呢?中间涉及的模块如此之多,有任何一个模块出了问题,Sentry是怎么快速恢复权限的呢?这篇文章将为你解答。
异常情况恢复
很有意思的是,Sentry做了详尽的异常情况恢复的逻辑设计
涉及模块
书接上回,本次讲解的相关组成结构主要为:(为了方便理解,我们改变了下顺序)
- Hive(HMS)
- Sentry Server(HMS Follower的启停)
- Hadoop NameNode(NN Plugin的插拔)
接下来,我们一个一个看
Hive挂掉啦
Hive挂掉是最好理解的情况,从一个流程的开头开始停掉后,后续的流程肯定是走不动了的。在Hive挂掉时,相关Path信息已然同步到了HMS中,如果有事件正好没有同步到Sentry,Sentry的HMS Follower也是实时监听HMS的情况,不管Hive(包括HiveServer2还是HMS Service)的进程是否存在,都能从HMS直接拉数据同步到Sentry Store中,直到所有事件被处理完。
简而言之,Hive进程挂掉不影响已有信息的同步,也不涉及异常情况的恢复,只是新的建表(新建Path)和权限操作无法处理罢了。
Sentry Server挂掉啦
Sentry Server挂掉,对于权限而言是一个很大的问题。因为这个时候,从Hive侧进行Path的创建,抑或是权限的操作,都无法通过HMS Follower及时同步到Sentry Store,以及Hadoop NameNode等其他组件中。
这个时候的异常恢复,咱们在第一篇讲的快照(SNAPSHOT_ID
)就派上用场了。
- Sentry Server重新启动,开始正常服务。
- Sentry Server在Sentry Store中的
AUTH_PATHS_SNAPSHOT_ID
表中新增一位,就是之前的最大值+1,作为新的快照id。 - Sentry Server从HMS中获取全部Path信息(还记得么,就是库/表与HDFS Location之间的映射关系),以最新的快照id,存储进入
AUTH_PATHS_MAPPING
和AUTH_PATH
等Path相关的表中。光从表的数据量来看,这两张表以及其他相关表的数据量直接翻了一倍。 - Sentry Server正常开始提供服务。
这里有几个细节需要关注:
- 异常恢复的只有Path相关数据,毕竟可以从完备的HMS中获得。Perm权限相关数据就直接丢失了。因为如果是Sentry承接权限校验,HMS中是不会存储权限相关信息的。这个时候,如果从Hive上执行手动授权之类的操作,会报错。
- 快照的存在是为了记录每一次HMS的元数据信息,因为每次都是全量同步,多来几次,HMS的数据量再大些,Sentry Store会有性能瓶颈。千万不要没事儿尝试着玩哦。
- 很特别的是,如果你手动修改
SENTRY_HMS_NOTIFICATION_ID
中的记录,无端的增加一个id,不管是否连续,在Sentry Server校验后发现与HMS中的事件id匹配不上后,也会当做是出现与Sentry Server挂掉的同等异常,立刻新增快照id,以及全量同步元数据。当然,我没研究过这块的代码,很有可能Sentry Server的重启,也会检测SENTRY_HMS_NOTIFICATION_ID
的值,也是很可能的。
Hadoop NameNode挂掉啦
Hadoop NameNode挂掉的效果和NN Plugin的插拔(配置配上还是删掉)是一样的,本质都是NN Plugin的线程启动了没有。
每一次NN Plugin的线程启动后,都会去SENTRY_PATH_CHANGE
和SENTRY_PERM_CHANGE
两个表中取最新的change_id
放在内存中,作为基础。而后每当扫描到新的change_id
出现,就同步这两个“事件表”的数据。一条数据里面直接写明了操作和具体的Path或者Perm信息,这也是为什么不去做元数据表扫描的原因,毕竟相比而言,后者扫描的表更多信息更杂些。
我们都知道,NameNode的元数据是存在内存中的,为了提升速度,但是确实有OOM的风险。NN Plugin的权限信息也是存储在内存中的。如果出现上述异常情况,那一旦NN Plugin恢复后,就会立刻去Sentry Store中同步全量的元数据信息。因为是全量的,上述两个“事件表”的信息就不那么合适了。NN Plugin会直接去AUTH_PATH
等Path表,和SENTRY_DB_PRIVILEGE
等Perm表中直接拉取所有的信息,按照第二篇文章说的映射结构进行内存存储。
所以就可以看出来,其实第一篇讲的数据库结构,在NN Plugin的使用上可以分为两类:
- “事件表”:一条记录是一个事件,包含相应的操作,操作对象,与操作人等。这些事件“阅后即焚”,Sentry Store中也有线程定时清理,不会存很久的时间,毕竟不会重复读取。
- “元数据表”:结构清晰,拆分有序,全量保存,就是为了防止这类情况需要重复读取的。