多租户过程记录一

多租户概念来源

             

        在一台服务器上运行单个应用实例,它为多个租户提供服务。传统,应用服务单个租户,数据库多部署在企业内部,数据私有,符合安全标准。云计算时代,数据公开,但是租户对数据安全还是有要求的。

 

设计的考量点

 

        如何对应用数据进行设计,以支持多租户?是要在数据的共享,安全隔离和性能间取得平衡。

 

数据设计的三种模式

 

        第一种,独立数据库。一个租户独享一个数据库实例,它提供最强分离。租户数据物理不可见,备份与恢复灵活。

        第二种,共享数据库,独立Schema。将每一个租户关联到同一个数据库的不同Schema。租户间数据彼此逻辑不可见,上层应用程序的实现和独立数据库一样简单,备份与恢复稍微复杂。schema在Mysql中就像一个database一样。schema在oracle中相当于用户,用户名可以代替schema。

        第三种,共享数据库,共享Schema,共享数据表。租户在数据表级别共享,它提供成本低。但是编程复杂,程序的数据访问需要用tenantld来区分不同租户。备份与恢复最复杂。

 

项目选择第三种方式

        表设计。增加一张tenant表,字段有tenant_id,tenant_name,tenant_code,is_stop,create_id,

create_time。后期讨论根据现实生活的情况,一个租户租了多长时间这个字段,租户时效,并且由程序自动控制;以及永久性租户字段。对于其他表是尽量让每一张表都有tenant_id这个字段标识,当然起维护作用的中间表就不需要这个字段。这个设计在数据量有一定的冗余,所以最后只将主表设计为有tenant_id这个字段,从表就直接去掉了这个字段。而且对于数据量比较大的表,无论是主表还是从表都依然保留,因为要考虑到后期的表分区,以及一些潜在的表可能进行分区。(得去理解oracle和mysql分区知识,一般就是range和list分区)。表里的索引知识以及联合索引知识也得去理解,并且结合sql语句,因为sql语句也决定了当前的索引是否起作用了,sql语句也是从后往前执行的

 

       session的设计。第一,用户登陆时将用户的TenantID信息保存于SESSION中。第二,在进行数据库访问操作前必须强制拦截验证TenantID是否为空。

 

      实体设计。一开始是抽象出一个tenant这个基类,让所有的实体类继承这个基类,这个设计未通过。这样子的设计好处就是对sql语句的改动其实并不大,因为tenant_id这个字段就存在于每一个实体中,根本无需作其他的改动。仔细想想也没有这个必要。最后把用户这个基础类添加了一个tenant_id这个字段,这样子当用户登录上来,这个标识自然存在于这个登录的对象中,需要的时候,只需获取就可以了。程序是将当前登录的用户存session。需要这个tenant_id这个标识的时候,直接从session中取就可以了。程序采用的有SessionManager这个类进行session管理,而且还有AppContext这个类型进行配合。

 

      存在的一般问题。有些表的数据量太大了,怎么处理?数据库层面,则是表分区,并且合理设置索引,配合有效的sql语句;在应用程序层面,则是采用单例模式。多个租户同时使用时,比如对于领取试卷的时候,肯定会反复地访问数据资源,这会造成数据库连接池的资源消耗,而且领取的试卷又很大,这个时候采用的是ehcache,并且由spring对这个ehcache进行管理,配置,启动注解,而且由@CachePut@Cacheable@CacheEvict配合使用,来避免反复连接数据而造成的资源浪费。而且,还考虑到以后潜在的某些表或者实体存在同样的这种情况,也可以采取类似的处理。

 

     潜在的问题。随着时间的推移,用户增多,性能开销?如此多数据怎么维护?

     一些以后可能附加的功能。数据大共享,运营商免费提供的资源如果共享?音频,视频,图片等放在其他服务器。是否支持逐级授权。

 

 

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值