微服务之可扩展性设计

349 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第26天,点击查看活动详情

可扩展性设计

4.1 横向扩展

横向扩展:指用更多的节点支撑更大量的请求。 纵向扩展:扩展一个点的能力支撑更大的请求。例如将磁盘升级为SSD。

4.2 扩展数据库后查询

4.2.1 带拆分键

拆分的时候携带拆分键,通过对拆分键进行路由查询,就知道查哪张表了,不然并行的去查所有表导致性能问题。

4.2.2 拆分库之后的关联查询

订单表和用户表是分别在不同的数据库,那么要想查询“订单金额大于100的用户”就比较麻烦。

方案1:建立多维度数据库

尝试建议一个综合数据库,相当于为了进行关联查询多冗余了一份数据。电商系统中,商品、价格、库存划分为了多个数据库。

可以建立一个综合数据库更新时,通过消息中间件更新到综合数据库内。 查询时,直接从综合数据库查询。

方案2:建立外部搜索引擎

通过分布式搜索引擎进行全文检索

方案3:通过分布式缓存

通过分布式缓存冗余数据。如果数据量比较少,可以采用这种方式。

4.2.3 数据库分表经典案例

案例1: 活动平台数据表水平切分

假设有一个活动平台,管理员可以创建活动,为活动添加用户,针对一个活动给用户发送促销短信或邮件提醒。

通常用户数据大的时候,会把用户单独在一个数据库中。活动和活动关系表放在另一个数据库中。

但是如果活动用户关系表数据量很大时,如果按活动进行分片,就会导致热点数据,因为有的活动关注的用户多,有的活动关注的用户少。 如果根据用户分片的话,那么要查询关注某活动的所有用户,就需要遍历所有分片查询。

实际上,关系数据就是两个id而已,存储空间不大。可以优先考虑做缓存,不做分区。

案例2:SNS数据表水平切分

比如微博、微信。他们主要结构包括用户表,用户关系表(谁关注了谁)、消息表(发的微博、朋友圈)。在微博中,首页通常是timeline(指你可以看到你关注的人的所有消息,通常按时间排序),还有一个页面是profile(自己或单个人发布的所有消息)。当消息的量很大时,要进行水平切片,那么如何保证查询不去遍历所有分片呢?

如果按照发布消息的用户id进行分片,那么查询自己或某个人的消息还好,只用一个分片内能查询到。但是要查所有关注者的消息,那就得遍历所有分片了。

可以再增加一个消息内容表,让所有timeline的数据在一个分片内取到。他带来的问题就是浪费资源。这也是Twitter采用的方案,由于国内的SNS存在大量僵尸用户,一般采用推拉结合的方式兼顾。

案例3:电商数据表水平切分

电商中以订单为典型,一个订单包含id,卖家id,卖家id三个重要的查询关键字。为了简化,先不考虑订单与子订单相关的内容。该如何选择水平切分呢?

方法1:外置搜索引擎查询

方法2:让订单id和买家id建立联系。在水平分表的时候可以截取买家id的后几位加在生成订单id的末尾。这样订单id和买家id就建立了联系。通过这两个条件查询都不用遍历所有表。