• 分层架构设计(转)


    1. 互联网分层架构的本质:

        1).互联网分层架构的本质,是数据的移动

        2).互联网分层架构中,数据的传输格式(协议)与数据在各层次的形态很重要

        3).互联网分层架构演进的核心原则与方法:封装与复用

            a.让上游更高效的获取与处理数据,复用

            b.让下游能屏蔽数据的获取细节,封装

    2. 互联网分层架构是一个很有意思的问题,服务化的引入,并不是越早越好:

        1).请求处理时间可能会增加

        2).运维可能会更加复杂

        3).定位问题可能会更加麻烦

    3. 当业务越来越复杂,垂直拆分的系统越来越多,基础数据服务越来越多,底层数据获取复杂性成为通用痛点的时候,就应该抽象出通用业务服务,简化数据获取过程,提高数据获取效率,向上游屏蔽底层的复杂性。

        这样的好处是:

        复杂的从基础服务获取数据代码,只有在通用业务service处写了一次,没有代码拷贝

        底层基础数据service接口发生变化,只有通用业务service一处需要升级修改

        如果有bug,不管是底层基础数据service的bug,还是通用业务service的bug,都只有一处需要升级修改

        业务web-server获取数据更便捷,获取所有数据,只需一个RPC接口调用

    4. 为啥要前后端分离

        1).一点点展现的改动,需要Java工程师们重新编译,打包,上线,重启tomcat,效率极低

        2).原先Java工程师负责所有MVC的研发工作,现在分为Java和FE两块,需要等前端和后端都完成研发,才能一起调试整体效果,不仅增加了沟通成本,任何一块出问题,都可能导致项目延期

            当业务越来越复杂,端上的产品越来越多,展现层的变化越来越快越来越多,站点层存在大量代码拷贝,数据获取复杂性成为通用痛点的时候,就应该进行前后端分离分层抽象,简化数据获取过程,提高数据获取效率,向上游屏蔽底层的复杂性。

            这样的好处是:

            复杂的业务逻辑与数据生成,只有在站点数据层处写了一次,没有代码拷贝

            底层service接口发生变化,只有站点数据层一处需要升级修改

            底层service如果有bug,只有站点数据层一处需要升级修改

            站点展现层可以根据产品的不同形态,传入不同的参数,调用不同的站点数据层接口

            除此之外:

            产品追求绚丽的效果,并对设备兼容性要求高,不再困扰Java工程师,由更专业的FE对接

            一点点展现的改动,不再需要Java工程师们重新编译,打包,上线,重启tomcat

           约定好json接口后,Java和FE分开开发,FE可以用mock的接口自测,不再等待一起联调

    5. 分库需求

        高并发大流量的互联网架构,一般通过服务层来访问数据库,随着数据量的增大,数据库需要进行水平切分,分库后将数据分布到不同的数据库实例(甚至物理机器)上,以达到降低数据量,增加实例数的扩容目的。

        一旦涉及分库,逃不开“分库依据”patition key的概念,使用哪一个字段来水平切分数据库呢:大部分的业务场景,会使用业务主键id。

        确定了分库依据patition key后,接下来要确定的是分库算法:大部分的业务场景,会使用业务主键id取模的算法来分库,这样即能够保证每个库的数据分布是均匀的,又能够保证每个库的请求分布是均匀的,

         实在是简单实现负载均衡的好方法,此法在互联网架构中应颇多。

    6. 究竟为什么要引入数据库中间件

         1). partition key上的单行查询

              典型场景:通过uid查询user

              场景特点:通过patition key查询;每次只返回一行记录

              解决方案:base-service层通过patition key来进行库路由

          2).非patition key上的单行查询

              典型场景:通过login_name查询user

              场景特点:通过非patition key查询;每次只返回一行记录

              解决方案1:base-service层访问所有库

              解决方案2:base-service先查mapping库,再通过patition key路由

                                  a.新建mapping库,记录login_name到uid的映射关系

                                  b.当有非 patition key的查询时,先通过login_name查询uid

                                  c.再通过patition key进行路由,最终返回一条记录

              解决方案3:基因法 

          3).patition key上的批量查询:

               典型场景:用户列表uid上的IN查询

               场景特点:通过patition key查询;每次返回多行记录

               解决方案1:base-service层访问所有库,结果集到base-service合并

               解决方案2:base-service分析路由规则,按需访问

                                   a.base-service根据路由规则分析,判断出有些数据落在库1,有些数据落在库2

                                   b.base-service按需访问相关库,而不是访问全库

                                   c.base-service合并结果集,返回列表数据

          4).非patition key上的跨库分页需求

              关于分库后,跨库分页的查询需求,详见《业界难题,跨库分页的四种方案》。

          5).本文写到这里,上述一、二、三、四、五其实都不是重点,base-service层通过各种各样的奇技淫巧,能够解决db水平切分后的数据访问问题,只不过:

               base-service层的复杂度提高了; 数据的获取效率降低了

               底层的复杂性会扩散到各个base-service,所有的base-service都要关注:

               patition key路由;非patition key查询,先mapping,再路由;先全库,再合并;先分析,再按需路由;跨库分页处理…

               这个架构图是不是看上去很别扭?如何让数据的获取更加高效快捷呢?

               数据库中间件的引入,势在必行。

               这是“基于服务端”的数据库中间件架构图:

                base-service层,就像访问db一样,访问db-proxy,高效获取数据

                所有底层的复杂性,都屏蔽在db-proxy这一层

                这是“基于客户端”的数据库中间件架构图:

                base-service层,通过db-proxy.jar,高效获取数据

                所有底层的复杂性,都屏蔽在db-proxy.jar这一层

                结论:

               当数据库水平切分,base-service层获取db数据过于复杂,成为通用痛点的时候,就应该抽象出数据库中间件,简化数据获取过程,提高数据获取效率,向上游屏蔽底层的复杂性。

  • 相关阅读:
    Oracle9i数据库移动过程
    基于索引的SQL语句优化之降龙十八掌
    activex发布步骤
    用ftpsupport进行ftp上传
    周五晚上看了变形金刚
    故宫游
    UTF8转GB2312
    跨数据库的视图【自己留着看】
    数学之美 - 布隆过滤器(Bloom Filter)【转】
    搜索引擎优化SEO的ppt讲义
  • 原文地址:https://www.cnblogs.com/Jtianlin/p/8902925.html
Copyright © 2020-2023  润新知