开发者学堂课程【高校精品课-厦门大学 -JavaEE 平台技术:设计- Redis 设计】学习笔记,与课程紧密联系,让用户快速学习知识
课程地址:https://developer.aliyun.com/learning/course/80/detail/15936
详细设计- Redis 设计
内容介绍:
一、将用户权限放入缓存中的步骤
二、对象模型设计
二、 Redis 设计
一、将用户权限放入缓存中的步骤
这个功能实现的想法就是让网关的速度变得较快,在 POST / admi nus ers / login 用户名密码登陆中做权限的校验。
在登陆中做权限校验的原因是用户登录成功后,不仅仅检验的是用户名和密码,还要把用户所有的权限放到缓存中。
正常的思维是用户登录后使用系统,有可能有极少数的用户是什么都不做就退出;大部分的用户是登录完成之后使用系统,所以会预期到登录完成后,大量的使用系统时去进行校权限。所以在登陆的时候,把用户的权限从数据库中计算出来放在缓存中,之后在缓存中计算权限,这样会比较快。但是,缓存并不是一个无限制的东西;在大家将它拿出来的时候,就不能将它永远放在缓存中。通常一个用户(是后台用户不是 shift 用户)会用一小时,最长使用时间为8小时。8小时之后就会在缓存中消失掉,因为缓存是有时效期的,到时间之后就会清除。如果不设定缓存清除时间,也会被清除掉。
如果拿一个东西放在缓存中,缓存不够,就会出现各种算法,最常见的为:最近最少使用的 AIRU 算法或者最近使用频次最少的 AIFU 算法,将符合算法条件的用户以及最近都没有登录的用户全部删除。比如,双11时,该用户登陆之后,从第一天的早上八点上班至第二天的早上八点,在晚上十二点使用的时候就可能会发现在内存的缓存中被赶出,所以这里提供了另外一个 API : GET /admi nus ers /privileges 用户的权限。这个 API 是如果用户在网关中发现自己的权限在缓存中不存在,就需要调用该 API 计算用户的权限,把它放到缓存中。
上图的 API 并不会被界面调;只有在网关处发现用户的权限值在内存中消失,才会调上图的 API ,让其重新产生。
所以在表面上的 API 中间是有两个 API 与计算用户的权限有关(不是校权限),只有把有用户的权限放上去以后,在结构上计算用户的权限。这就带来一个问题:在缓存中间储存何种结构,可以进入用户的权限。
二、对象模型设计
下图是在 ER 图上做的基础对象模型设计。
如果是一个经典的面向对象设计,它会把对象模型储存到缓存中,之后每次用户拿到对象模型就可以计算自己的权限。大家知道这里有两个问题:第一个问题,对象模型很大,它有很多的属性是与校权限没有关系的,比如用户的密码、电话号码、 email 、名字、图片等是与权限没有关系的;在任何角度而言都没有将它们放在内存中的必要性,因为用户在使用过程中并不会特别要求关注;比如,它的名字可能会频繁一点,但是其他的东西应该都很少,而且看名字的地方也不是特别多,尤其
是 email 、电话号码、密码等等都不会看。同样,角色中的名字虽然不多,但是一般也不会去看;在权限中间, id 和 name 也不太会去看。
所以每一个对象模型的中间,都会有一部分的属性对于校权限而言是没有意义的。大家知道缓存是一个有效的东西,速度很快,但是很贵、容量有限,所以在把一个东西放到缓存中时,是希望它在缓存中所占空间是越少越好的。对于校权限而言,它要放的就是用户的 id 作为 key ,之后值就可以直接决定用户的权限是什么。
三、 Redis 设计
其他的东西放入缓存中的意义不大,所以设计了在缓存中储存的东西。大家知道 Redis 是一个值键对的数据库,所以它只能储存一个对象,当然它还有更复杂的结构可以储存 list 、集合等等。大家现在看到的是权限,权限的 key 是 “ p _”+用户 id ,因为用户还有其他信息要缓存到这里,比如用户的名字;如果说是高频次使
用的话,也会将其进行缓存,它使用的是另一个东西,不会与权限混在一起。
因为用户要权限和用户要名字是在两个不同的场合,极少有用户同时要知道名字和权限两个信息,所以就没有必要将这两个信息存储到一起。可以分别用两个不同的东西做存储,大家现在可以看到存储的是用户的权限,而权限使用的是 Redis 中叫做 BitMap 的结构, BitMap 结构其实并不是 Redis 基础的存储结构; Redis 基础的存储结构是字符串和数据结构、列表、集合、排序列表、哈西曼基础的5种数据
类型。
BitMap 的形式是在字符串的基础上改进而成的,即它用一个字符串储存二进制的位图。
Redis 的字符串可以储存非常大的内容,最大可以储存512兆单个值(基本用不到)。单个值512兆,两个值占1 G ,二十个值就占20 G ,所以一般是不会用到这么大的值。
但是对于权限而言, BitMap 放到结构中是没有问题的,因为权限总共有三四百位,最多一千位,1024位有一千个值;所以打算用 BitMap 存储权限位。这里存在的问题是,对象模型如下图。