Apache Sentry,看这篇就够啦!

sentry-logo.png

CDH初始提供的权限组件就是Apache Sentry,经典的RBAC模型可以很好的支撑server、database、table等在用户的role和group之间的权限管控,打通了Hive和HDFS,也支持impala的权限识别,基本能满足一个公司70%的使用场景。

但是,

Spark不属于CDH提供的组件之一,也没办法使用原生Sentry进行权限管控。

对于uri的权限存在缺陷,不能直接同步到HDFS上,同时对View的权限也不支持。

于是为了解决这些事,我开始梳理Sentry的设计逻辑,以期满足剩下30%的使用需求。

今天,就从数据库设计开始吧!

以下表述来自Sentry 1.5版本

这是一篇平平无奇的纯干货


库表理解

Sentry的设计逻辑虽然是RBAC的模型,但是为了支撑大数据权限,从内容上,它可以将表大体分为两类:Path和Perm。

  • Path

    即与路径相关,也就是与HDFS路径相关,其相关的表当发生新建、修改、删除路径时会有数据变化

  • Perm

    即与权限相关,涉及Hive、Impala和HDFS等组件的权限,当权限发生变化(只能从Hive端或Impala端进行权限调整)时相关表数据会有变化

接下来,先说下每一张表的结构内涵

AUTH_PATH

  • 用途:记录受权限管控的路径,原生CDH体系中基本都是HDFS路径
  • 从属类别:Path
  • 列释义
    • PATH_ID:路径ID,主键,来自SEQUENCE_TABLE,不过Sentry在这里做了很完善的兼容,如果max(PATH_ID)比SEQUENCE_TABLE中的记录大,那么就直接取max(PATH_ID) + 1,并修改SEQUENCE_TABLE的值。
    • PATH_NAME:路径。有意思的是,这里的路径会做一层清理,开头不是/,或者hdfs://,这样的设计可以兼容云存储的路径(不同的协议,例如cos://等)。
    • AUTHZ_OBJ_ID:外键,AUTHZ_PATHS_MAPPING的主键,用于关联,详细解释可以看下面。

AUTH_PATHS_MAPPING

  • 用途:记录受权限管控的实体和路径之间的关系,这里的实体为Hive元数据库中的database、table等,在这个表里都属于OBJ
  • 从属类别:Path
  • 列释义:
    • AUTHZ_OBJ_ID:受权限管控的实体主键。与上面的PATH_ID一样,也是来自SEQUENCE_TABLE
    • AUTHZ_OBJ_NAME:实体名称,例如库名、表名等。有意思的是,视图是虚拟表,在Sentry中会认为是Table类型(与物理表类型一样,但是它没有对应的PATH)
    • CREATE_TIME_MS:创建时间
    • AUTHZ_SNAPSHOT_ID:外键,快照ID,AUTHZ_PATHS_SNAPSHOT_ID的主键。这是整个Sentry一致性保证的核心,详情以后会详述。

AUTH_PATHS_SNAPSHOT_ID

  • 用途:快照记录。快照是个非常哇塞的设定。
  • 从属类别:Path
  • 列释义:
    • AUTHZ_SNAPSHOT_ID:快照ID,就一列,每次递增1,初始是0。

SENTRY_DB_PRIVILEGE

  • 用途:库表结构相关权限记录。使用Hive的权限数据都在这上面。权限包括具体的操作和目标实体。如果是一个目标实体的多个操作权限,那就是多行。
  • 从属类别:Perm
  • 列释义:
    • DB_PRIVILEGE_ID:权限ID,主键,也是来自SEQUENCE_TABLE
    • PRIVILEGE_SCOPE:权限范围,例如server(集群范围),database(库范围),table(表范围)等
    • SERVER_NAME:集群名称
    • DB_NAME:库名称
    • TABLE_NAME:表名称,上面提到过,视图view在这里也会被当作表,其权限范围也是Table。如果是库范围,这里会填写*,代表所有表。下面的列名称同样的道理。
    • COLUMN_NAME:列名称
    • URI:路径名称。但是Sentry这里的路径不会同步给HDFS,所以如果想要直接通过Hive给某个HDFS路径授权是做不到的。至少原生的Sentry做不到。
    • ACTION:操作。包括select,all等
    • CREATE_TIME:创建时间
    • WITH_GRANT_OPTION:true/false,拥有该实体的权限是否同时拥有对该实体授权的权限,(管理员角色会跳过这个判断,设置管理员角色在Sentry的配置文件中或CDH的配置中)。绝大部分情况下是false,因为会使用统一的管理员账户进行授权,而不会把单独实体的权限下放到其他角色中。

SENTRY_GM_PRIVILEGE

  • 用途:GM是Generic Model的缩写,说白了就是通用权限模型。SENTRY_DB_PRIVILEGE模型是典型的为Hadoop生态定制的,支持权限实体层级从Server开始细化到Column,还能支持Uri,但很明显,这样的体系结构在其他引擎中并非通用。GM就是为了适配更常用的实体模型而设计的,更符合RBAC的设计理念。他的主要设计就是预定义resource0-3,代表实体的四个层级,(在sentry1.5版本最多支持4个层级)。当然这样的设计在现在看来还有优化空间,但是对于其他引擎的对接,这样的设计使用还是够的。
  • 从属类别:Perm
  • 列释义:
    • GM_PRIVILEGE_ID:权限id
    • ACTION:操作
    • COMPONENT_NAME:组件名称,Service的下一层级,服务内的组件名称
    • CREATE_TIME:创建时间
    • WITH_GRANT_OPTION:
    • RESOURCE_NAME_0:受权限管控的第一层级资源名称
    • RESOURCE_NAME_1:第二层级
    • RESOURCE_NAME_2:第三层级
    • RESOURCE_NAME_3:第四层级
    • RESOURCE_TYPE_0:受权限管控的第一层级资源的类型
    • RESOURCE_TYPE_1:第二层级
    • RESOURCE_TYPE_2:第三层级
    • RESOURCE_TYPE_3:第四层级
    • SCOPE:权限范围,默认都是Service范围,从这里就可以看出DB那张表是做了定制化设计的,通用的干脆先都写成最外层限制,具体的根据resource填写的判断
    • SERVICE_NAME:需要管控的服务名称,应该是为了兼容不同引擎组件共用sentry做权限管控而设计的

SENTRY_GROUP

  • 用途:group信息,对应HDFS上面的Group
  • Perm
  • 列释义:
    • GROUP_ID:group主键
    • GROUP_NAME:group名称
    • CREATE_TIME:创建时间

SENTRY_HMS_NOTIFICATION_ID

  • 用途:对接Hive Metastore(HMS)的event_id,用这个id保持与HMS内信息的一致。这个逻辑与刚刚那个快照一样哇塞,下篇文章详细描述下如何哇塞。
  • 从属类别:Path & Perm(不管啥玩意儿变,它都会跟着变)
  • 列释义:
    • NOTIFICATION_ID:对标HMS的event_id,代表当前的最新事件编号。数字是一直累加的,不会后退。Sentry Server和Sentry Plugin也都持有上一次的NOTIFICATION_ID,随时和库里的做对比进行检测。如果不同就触发更新。

SENTRY_PATH_CHANGE

  • 用途:PATH更改事件记录。其中,包括创建路径(创建库、表),删除路径(删除库、表),修改路径等都会生成事件,记录在这个表中。HDFS读取更新的事件就是从这张表读取。
  • 从属类别:Path
  • 列释义:
    • CHANGE_ID:主键,递增。(Sentry的表设计并没有使用MySQL的auto_increment,也就是由server自己控制自增处理,个人盲猜原因之一是因为这个项目的启动时间还是分布式刚开始兴起的时候,使用单机的思路来做的处理。这里给我们后续做自定义补充开发造成了很大的麻烦)
    • NOTIFICATION_HASH:上面那个NOTIFICATION_ID的hash结果,反正也是唯一值,从实际上来看既没有被用作校验,也没有被用作实际权限内容,甚至可以直接用Java的UUID来代替。只要在表里是唯一的就行。
    • CREATE_TIME_MS:创建时间
    • PATH_CHANGE:Sentry内部定义的结构,用于和HDFS上的Sentry Plugin进行内容的交互。Path改变的信息(增加或删除)以及这次改变对应的Notification_id会被按照一种格式(类似于json,但是要复杂很多)组装到这里;Sentry Plugin从这里取到后,解析出来,翻译成HDFS的POXIS权限保存在NAMENODE的内存中,用于路径使用的权限控制。有空单独写一篇文章梳理一下这个结构。

SENTRY_PERM_CHANGE

  • 用途:从表名上看就能知晓,这是与上面的SENTRY_PATH_CHANGE表核心逻辑是一样的。当权限相关的信息存在修改时,例如授权,或者回收权限等,这里都会新增一条记录。
  • 从属类别:Perm
  • 列释义:
    • CHANGE_ID:主键,递增。
    • CREATE_TIME_MS:创建时间。
    • PATH_CHANGE:权限的修改伴随着对应HDFS目录权限的修改和调整,这里的记录就是这些内容。

SENTRY_ROLE

  • 用途:顾名思义,角色表。
  • 从属类别:Perm
  • 列释义:
    • ROLE_ID:角色id
    • ROLE_NAME:角色名称。
    • CREATE_TIME:创建时间。

SENTRY_ROLE_DB_PRIVILEGE_MAP

  • 用途:角色和权限信息的关联表,就是n:n的两个表之间,使用id对接的那个表。
  • 从属类别:Perm
  • 列释义:
    • ROLE_ID:角色id
    • DB_PRIVILEGE_ID:权限id,SENTRY_DB_PRIVILEGE的主键。
    • GRANTOR_PRINCIPAL:授权方。也是角色名称。

SENTRY_ROLE_GM_PRIVILEGE_MAP

  • 用途:与上面类似,角色和通用模型权限的关联表。
  • 从属类别:Perm
  • 列释义:
    • ROLE_ID:角色id
    • GM_PRIVILEGE_ID:权限id

SENTRY_ROLE_GROUP_MAP

  • 用途:角色和组之间的关联表,俩n:n表之间,id对接的那个表
  • 从属类别:Perm
  • 列释义:
    • ROLE_ID:角色id
    • GROUP_ID:组id
    • GRANTOR_PRINCIPAL:授权的角色名称。从这个设计上看,这个表应该也是围绕Hadoop生态体系定制的。

SENTRY_USER

  • 用途:用户元信息。
  • 从属类别:Perm
  • 列释义:
    • USER_ID:用户id
    • USER_NAME:用户名
    • CREATE_TIME:创建时间。

SENTRY_USER_DB_PRIVILEGE_MAP

  • 用途:顾名思义,用户权限关联表。
  • 从属类别:Perm
  • 列释义:
    • USER_ID:用户id
    • DB_PRIVILEGE_ID:权限id,表SENTRY_DB_PRIVILEGE的主键。
    • GRANTOR_PRINCIPAL:授权的用户名。

SENTRY_VERSION

  • 用途:Sentry的版本信息表。没什么实际意义,毕竟许多apache的项目都会设计这样的表用于从元数据层记录服务的版本号等信息,另一方面,如果涉及不同版本服务共用这一套元数据库,这里将记录多条信息。
  • 从属类别:common(公用)
  • 列释义:
    • VER_ID:Sentry安装版本
    • SCHEMA_VERSION:版本
    • VERSION_COMMENT:备注

SEQUENCE_TABLE

  • 用途:非常神奇的定义了多个上述表的下一个主键。应该是为了用于高可用部署下的id递增唯一性。从代码上来看,除了这里有记录,每一个Sentry Server中也有内存记录,这个记录会按照某一个频率(一般好像是0.5s,具体有配置处理)刷新读取当前目标表的主键,在具体插入时会和这张表的信息,以及目标表的主键做对比处理,最终取最大值。
  • 从属类别:common(公用)
  • 列释义:
    • SEQUENCE_NAME:部分表对应的类信息。举例子而言,org.apache.sentry.provider.db.service.model.MPath对应的是AUTH_PATH表的主键
    • NEXT_VAL:下一个主键id,一般就是对应表的当前最大主键id+1

打算认真写一些文章了,纯原创,转载需标注哦~
掘金号:无糖薄荷

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

推荐阅读更多精彩内容