分布式

谈谈分布式锁、以及分布式全局唯一ID的实现比较?

分布式锁实现方式及比较

  1. 为什么需要分布式锁?

    1. 效率:避免不同节点重复相同的工作,这些工作会浪费资源。比如针对一个操作发多封邮件。
    2. 正确性:避免破坏正确性的发生,比如多个节点操作了同一条数据,其中一个操作结果被覆盖了,造成数据丢失。
  2. 常见实现方式

    1. 数据库
      1. 表的一行数据表示一个资源,select..for update来加锁,可同时存节点信息,支持重入。
      2. 理解简单,但需要自己实现,以及维护超时、事务和异常处理等,性能局限于数据库,性能相对比较低,不适合高并发场景。
    2. zookeeper
      1. curator封装 – 具体怎么用还没看过呢
      2. Zk 排他锁和共享锁有区别。排他锁,利用zk有序节点,序号最小的节点表示获取到锁,其他未获取到锁的节点监听自己的前一个节点。 (共享锁,能获取到资源都算?回家再看看。)还有个读写锁,一个节点获取读锁,只要序号小于他的都为读锁,就表示获取到读锁;一个节点获取写锁,需要自己的序号最小,才表示获取到写锁。可重入锁之类的,zk节点写值吧,原理和Java的reentrantLock类似,获取多少次,state自加多少次,解锁再一次次自减,直到state为0表示完全释放。
      3. (文章里说zk分布式锁和数据库mysql差不多。。真的么)
    3. redis setNX
      1. 自己参照一篇文章实现的比较简单,主要利用setNX,不支持重入,非公平。有超时释放,有加锁身份,解锁原子性
      2. 下面的文章里介绍的Redission。不太了解,加锁原子性lua脚本,用了hset,hashmap的结构,key是资源,value是锁定次数,可重入。。还有公平锁的实现。。。

    分布式锁

分布式全局唯一ID/分布式ID生成器 实现方式及比较

  1. uuid

    1. 缺点:长,占用空间大,间接导致数据库性能下降
    2. 缺点:不是有序的,导致索引在写的时候有过多的随机写
  2. 数据库自增主键

    1. 缺点:完全依赖于数据库,有性能瓶颈
    2. 缺点:不易扩展
  3. snowflake Twitter,Scala实现的…

    1. 雪花算法,带有时间戳的全局唯一ID生成算法

    2. 固定ID格式:

      1
      2
      3
      41位的时间戳(精确到毫秒,41位的长度可使用69年)
      10位的机器ID(10位长度最多支持1024个服务器节点部署)
      12位的计数序列号(12位支持每节点每毫秒最多生成4096个序列号)
分布式锁的实现方式,zk实现和Redis实现的比较

实现方式:CAP的应用

  1. MySQL唯一索引

    1. 实现:锁名称建立唯一索引,先插入数据的线程获得锁
    2. 缺点:完全依赖数据库的可用性(单点问题,无主从切换)和性能
  2. Redis

    1. 实现:setnx key value expire_time
    2. 优缺点:为解决无主从切换的问题,可以使用Redis集群,或者sentinel哨兵模型。当master节点出现故障,哨兵从slave中选取节点称为新master节点。文章说,Redis集群的复制是AP模式,可能存在数据不一致,导致存在两个线程获得到锁的情况。(一个线程在原master获得锁,另一个线程在新master获得锁)
    3. 对数据一致性非常敏感的场景,建议使用CP模型(比如zk)
  3. zk

    1. 实现:

      1. 线程向zk的锁目录,申请创建有序的临时节点
      2. 如果建成的节点序号最小,表明获得到锁
      3. 如果序号非最小,监听自己的前一个节点
      4. 删除节点表示释放锁;当获取锁的客户端异常、无心跳,临时节点会被删除,也表示释放锁
    2. 优缺点:CP模式,zk的分布式锁比Redis的可靠,但Redis的性能更高。要根据自己的业务场景,再选型。

对一致性哈希的理解

一致性哈希算法

  1. 求出各节点的哈希值,将其配置到0~2^32的圆(continuum)上

  2. 用同样方法求出存储数据的哈希值,映射到相同的圆上

  3. 从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个节点上。如果超过2^32仍然找不到节点,就保存到第一个节点上

  4. 【如果添加一个节点node5,只会影响该节点的逆时针方向的第一个节点node4会受到影响(原来在node4上的数据要重新分配一些到node5上)】

  5. 一致性哈希算法对于节点的增减都只需重定位环空间中的一小部分数据,具有较好的容错性和可扩展性

  6. 在服务节点太少时,容易因节点分部不均匀而造成数据倾斜问题,可引入虚拟节点机制,即对每一个服务节点计算多个哈希,每个计算结果位置都放置一个此服务节点,称为虚拟节点。同时数据定位算法不变,只是多了一步虚拟节点到实际节点的映射。

    image-20200528142813487

对分布式数据一致性的理解

https://juejin.im/post/5ce7b325e51d45772a49ac9d

  1. 数据不一致性的情形

    1. 主库、从库和缓存的数据一致性:相同数据冗余。为保证数据库的高可用和高性能,会采用主从(备)架构并引入缓存。数据不一致存在于数据冗余的时间窗口内。
    2. 多副本数据之间的数据一致性:相同数据副本。一份数据有多个副本存储到不同节点上,客户端可以访问任一节点进行读写。常用协议包括Paxos、ZAB、Raft、Quorum、Gossip等。
    3. 分布式服务之间的数据一致性:微服务架构下,不同服务操作不同的库表,要求库表间要保持一致(等价于分布式事务) – 【感觉题目问的是这个】
  2. 对CAP理论的理解 https://www.zhihu.com/question/54105974/answer/139037688

    C代表一致性,A代表可用性(在一定时间内,用户的请求都会得到应答),P代表分区容忍性。

    一个分布式系统里面,节点组成的网络本来应该是连通的。然而可能因为一些故障,使得有些节点之间不连通了,整个网络就分成了几块区域。数据就散布在了这些不连通的区域中。这就叫分区。

    当你一个数据项只在一个节点中保存,那么分区出现后,和这个节点不连通的部分就访问不到这个数据了。这时分区就是无法容忍的。

    提高分区容忍性的办法就是一个数据项复制到多个节点上,那么出现分区之后,这一数据项就可能分布到各个区里。容忍性就提高了。

    然而,要把数据复制到多个节点,就会带来一致性的问题,就是多个节点上面的数据可能是不一致的。要保证一致,每次写操作就都要等待全部节点写成功,而这等待又会带来可用性的问题。

    总的来说就是,数据存在的节点越多,分区容忍性越高,但要复制更新的数据就越多,一致性就越难保证。为了保证一致性,更新所有节点数据所需要的时间就越长,可用性就会降低。

  1. 理解数据库本地事务 分布式事务

    1. ACID
      1. 原子性 atomicity:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
      2. 一致性 consistency:事务的执行前后,是从一个一致性状态转移到另一个一致性状态。【是通过原子性和隔离性保证的。】
      3. 隔离性 isolation:事务并发执行时,每个事务有各自完整的数据空间。有不同的隔离级别,大部分通过锁实现。
      4. 持久性 durability:事务只要成功执行,对数据库所做的更新会永久保存下来。
    2. 隔离级别
    3. innodb实现原理:主要通过锁和日志来保证ACID
      1. 通过锁机制和mvcc实现隔离性
      2. redo log(重做日志)实现持久性
      3. undo log实现原子性和一致性【可以回滚】
  2. 分布式事务 – 主要是要保证原子性

    1. 分布式事务

      指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。

      一次大操作由不同的小操作组成,小操作分布在不同的服务器上,且属于不同的应用,分布式服务需要保证这些小操作要么全部成功,要么全部失败

    2. 分布式事务的场景

      1. Service多个节点 – 指微服务等,比如一个交易平台,订单、库存、余额等在不同的服务下,一次交易需要原子性得更新。
      2. resource多个节点 – 指分库分表了,比如转账双方的余额在不同的表里,一次转账双方都要正确更新。
    3. 理论

      1. CAP
      2. BASE
    4. 解决方案

      1. 2PC
        1. 第一阶段:预提交,并反映是否可以提交。【事务管理器要求每个涉及到事务的数据库预提交(precommit)此操作,并反映是否可以提交.】
        2. 第二阶段:提交,或者回滚。【事务协调器要求每个数据库提交数据,或者回滚数据。】
        3. 优点:实现成本低
        4. 缺点:单点问题(事务管理器单点,可能引起资源管理器一直阻塞),同步阻塞(precommit后,资源管理器一直处于阻塞中,直到提交、释放资源),可能存在数据不一致(比如协调者发出了commit通知,但只有部分参与者收到通知并执行了commit,其余参与者则没收到通知处于阻塞状态,就产生不一致了)
      2. TCC
        1. try - confirm - cancel
        2. 协调者变成多点,引入进群
        3. 引入超时,超时后进行补偿,并且不会锁定整个资源,缓解同步阻塞
        4. 数据一致性:通过补偿机制,由业务活动管理器控制一致性
      3. 本地消息表:核心是将需要分布式处理的任务通过消息日志的方式来异步执行。消息日志可以存储到本地文本、数据库或消息队列,再通过业务规则自动或人工发起重试。
      4. MQ事务
      5. SAGA
      6. seata

分布式事务

描述分布式事务之TCC服务设计?
  1. 不了解

  2. TCC分布式事务 try - confirm - cancel

高并发&高性能&高可用系统设计

高并发&高性能&高可用
  1. 高并发:系统能够同时、并行处理很多请求,常用指标响应时间、吞吐量、并发用户数、QPS

    如何提高:

    1. 垂直扩展
      1. 增加单机硬件性能,比如CPU增加核数、升级更好的网卡,换好的硬盘,扩充内存
      2. 提升单机架构性能。比如使用缓存,使用异步增加单服务吞吐量
    2. 水平扩展
      1. 增加服务器数量
  1. 高性能:程序处理速度快,占用内存少,CPU占用率低

    高并发和高性能紧密相关,提供性能大部分可以提高并发

    增加服务器资源(内存、CPU、服务器数量)绝大部分能提高并发和性能

    注意事项:

    1. 避免因为io阻塞让CPU闲置,浪费CPU

    2. 避免频繁创建、销毁线程,导致浪费资源在调度上

  1. 高可用:减少停工时间,保持服务的高度可用性(一直能用)

    全年停机不超过31.5秒

    6个9:一直能用的概率为99.9999%

    注意事项:

    1. 避免单点
    2. 使用集群
    3. 心跳机制,监控服务器状态,挂了就进行故障修复
限流算法

缓存:提升系统访问速度和增大系统处理容量

降级:当服务器压力剧增的情况下,根据当前业务情况对一些服务和页面有策略地降级,以此释放服务器资源以保证核心任务的正常运行

限流:限流的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理

限流算法:

  1. 固定窗口法

    1. 实现:固定时间内限定个数,比如限定每分钟100个请求
    2. 缺点:无法应对两个时间边界内的突发流量。比如在计数器清零的前一秒和后一秒都进来100个请求,那么系统短时间内就收到了两倍(200个)请求,有可能超负荷。
    3. 原因:统计精度不够
  2. 滑动窗口法

    1. 实现:简单来说就是随着时间的推移,时间窗口也会持续移动,有一个计数器不断维护着窗口内的请求数量,这样就可以保证任意时间段内,都不会超过最大允许的请求数。例如当前时间窗口是0s~60s,请求数是40,10s后时间窗口就变成了10s~70s,请求数是60。
    2. 可以用Redis有序集合实现..
    3. image-20200524153228157
    4. 缺点:还是不能解决细粒度请求过于集中的问题,比如限制一分钟60个请求,但在59s时发送了60个请求过来。
  3. 漏桶算法

    1. 算法思想:与令牌桶算法有点相反。不限制流入速率,但以固定的速度将水流出。如果流入速度太大会导致水满溢出,溢出的请求被丢弃。
    2. 实现一:基于queue。queue的大小表示桶的大小,queue满了请求会被拒绝;另维护一个定时器,根据设定的出水速度去queue中取一个任务,比如限定一秒钟5个请求,就200ms去取一个任务,取到就执行,取不到就轮空。
    3. 实现二:基于meter,计数器。【…写的不是很清楚,看起来和固定窗口法很像了,没有体现固定的出水,只表示时间粒度比较细】
  4. 令牌桶法

    1. 算法思路:以固定的速率生成令牌,把令牌放到固定容量的桶里,超过桶容量的令牌则丢弃。每来一个请求获取一次令牌,只有获得令牌的请求才能放行,没有获得令牌的请求丢弃。
    2. 【令牌是匀速生成的,如果请求超高频,则完全被限制成令牌的生成速率;如果请求突发,也最多只允许令牌数的上限。】
    3. Guava RateLimiter
  5. 令牌桶与漏桶的比较

    1. 漏桶能够强行限制数据的传输速率

    2. 令牌桶限制数据的平均传输速率,允许某种程度的突发传输

    3. 【看起来比较喜欢令牌桶】

两次点击,怎么防止重复下订单?

两次点击的场景

  1. 没有刷新和前端控制,同一个按钮点了两次
  2. 网络问题以为失败(其实成功了)又提交了一次
  3. rpc等重试服务
  4. 刷新前后各点一次(或者表单刷新又提交了一次)
  5. 点了后退按钮,再前进

处理方案:

  1. 前端
    1. 弹出确认界面,或disable入口并倒计时等
  2. 后端
    1. 约定【所谓重复订单,需要定义这是相同的订单】,需要和客户端配合实现
      1. 比如支付可以用订单ID作判断
      2. 如果是下单,可以用uuid或服务端先生成一个全局唯一的订单ID,客户端如果未接收到下单成功的响应,多次重试都用这一个订单ID来提交。(如果是刷新,需要客户端去服务端请求最新购物车数据,已成功下单的商品已被移除;如果是未刷新页面的重试,则使用同一个订单ID;或者提示用户刷新、提示是否重试)
    2. 后端的去重判断方式 https://www.cnblogs.com/jett010/articles/9056567.html – 本质上分布式锁的应用
      1. 基于数据库中对应订单ID的状态做判断,ID已存在(下单),或者状态已变更(修改订单,比如取消、退款等)。如果查询和更新是分开的两个操作,会存在时间差,比如查询完后状态被别的线程修改了,可以用加数据库锁的方式解决这个问题(悲观锁或乐观锁)
      2. 利用数据库唯一性索引,性能比较低
      3. Redis分布式锁,key是订单ID,要点是加锁和解锁的原子性
      4. ps redis的计数器是原子操作 https://redis.io/commands/incr
秒杀场景设计,应付突然的爆发流量

一个秒杀系统的设计思考

两个核心问题:并发读、并发写

对应到架构设计,就是高可用、一致性和高性能的要求

  1. 高性能:涉及高读和高写。

    核心理念:高读->尽量“少读”或“读少”,高写->数据拆分

    1. 动静分离:将页面拆分,静态部分做CDN缓存(秒级失效,若干CDN节点),动态部分异步请求。

      数据拆分、静态缓存、数据整合(指动态数据、静态数据怎么整合在一起,一种服务端将动态数据插入到静态页面,另一种前端异步调用)

    2. 热点优化

      1. 热点操作:零点刷新、零点下单、零点加购物车等,属于用户行为不好改变,但可以做一些限制,比如用户频繁刷新页面时进行提示阻断。

      2. 热点数据:

        1. 热点识别:分为静态热点(可以提前预测的。大促前夕,可以根据大促的行业特点、活动商家等纬度信息分析出热点商品,或者通过卖家报名的方式提前筛选;另外,还可以通过技术手段提前预测,例如对买家每天访问的商品进行大数据计算,然后统计出 TOP N 的商品,即可视为热点商品)和动态热点(无法提前预测的。比如直播临时做了个广告可能导致一件商品短期内被大量购买)。

          动态热点的识别实现思路:1. 异步采集交易链路各个环节的热点key信息,比如nginx采集访问url或agent采集热点日志(一些中间件本身已具备热点发现能力),提前识别潜在的热点数据。2. 聚合分析热点数据,达到一定规则的热点数据,通过订阅分发推送到链路系统,各系统根据自身需求决定如何处理热点数据,或限流或缓存,从而实现热点保护

          最好做到秒级实时,这样动态发现才有意义。实际上也是对核心节点的数据采集和分析能力提出了较高的要求。

        2. 热点隔离:将热点数据隔离出来,不影响非热点数据的访问。 – 【我怎么觉得参与秒杀的商品都可以直接作为热点呢??】

          1. 业务隔离。秒杀作为一种营销活动,卖家需要单独报名,从技术上来说,系统可以提前对已知热点做缓存预热 – 【静态热点吧..】
          2. 系统隔离。系统隔离是运行时隔离,通过分组部署和另外 99% 进行分离,另外秒杀也可以申请单独的域名,入口层就让请求落到不同的集群中 – 【也是静态热点吧..】
          3. 热点数据,可以启用单独的缓存集群或者DB服务组,从而更好的实现横向或纵向能力扩展 – 【可以是动态的,假如一个商品被动态标记为热点后】
        3. 热点优化:对这1%的数据做针对性的优化

          1. 缓存:热点缓存是最为有效的办法。
          2. 限流:流量限制更多是一种保护机制。–属于有损服务。
    3. 系统优化:提升硬件水平、调优JVM性能、代码层面优化

      1. 代码层面优化:1. 减少序列化(减少RPC调用,一种可行的方案是将多个关联性较强的应用进行 “合并部署”,从而减少不同应用之间的 RPC 调用(微服务设计规范))2. 直接输出流数据(只要涉及字符串的I/O操作,无论是磁盘 I/O 还是网络 I/O,都比较耗费 CPU 资源,因为字符需要转换成字节,而这个转换又必须查表编码。所以对于常用数据,比如静态字符串,推荐提前编码成字节并缓存,具体到代码层面就是通过 OutputStream() 类函数从而减少数据的编码转换;另外,热点方法toString()不要直接调用ReflectionToString实现,推荐直接硬编码,并且只打印DO的基础要素和核心要素– 这整段不是很懂,toString懂啊哈哈)3. 裁剪日志异常堆栈,超大流量下频繁地输出完整堆栈,会加剧系统当前负载(可以通过日志配置文件控制异常堆栈输出的深度)4. 去组件框架:极致优化要求下,可以去掉一些组件框架,比如去掉传统的 MVC 框架,直接使用 Servlet 处理请求。这样可以绕过一大堆复杂且用处不大的处理逻辑,节省毫秒级的时间,当然,需要合理评估你对框架的依赖程度
  2. 一致性:秒杀场景下的一致性问题,主要是库存扣减的准确性问题

    1. 减库存的方式:

    2. 下单减库存(用户体验好,但存在恶意下单不付款的问题)

      1. 付款减库存(用户体验差,很多人下单成功但有人不能付款)

      2. 预扣库存:缓解了以上两种方式的问题。预扣库存实际就是“下单减库存”和 “付款减库存”两种方式的结合,将两次操作进行了前后关联,下单时预扣库存,付款时释放库存。

        劣势:并没有彻底解决以上问题。比如针对恶意下单的场景,虽然可以把有效付款时间设置为 10 分钟,但恶意买家完全可以在 10 分钟之后再次下单。

        实际业界也多用这种方式,下单后一般都有个 “有效付款时间”,超过该时间订单自动释放,是典型的预扣库存方案。

      3. 恶意下单的解决方案主要还是结合安全和反作弊措施来制止。比如,识别频繁下单不付款的买家并进行打标,这样可以在打标买家下单时不减库存;再比如为大促商品设置单人最大购买件数,一人最多只能买 N 件商品;又或者对重复下单不付款的行为进行次数限制阻断等

      4. 超卖分为两种:1. 商家可以补货的,允许超卖;2. 不允许超卖,限定库存字段不能为负数:1)一是在通过事务来判断,即保证减后库存不能为负,否则就回滚;2)直接设置数据库字段类型为无符号整数,这样一旦库存为负就会在执行 SQL 时报错

    3. 一致性性能的优化

      1. 高并发读:“分层校验”。即在读链路时,不做一致性校验,只做不影响性能的检查(如用户是否具有秒杀资格、商品状态是否正常、用户答题是否正确、秒杀是否已经结束、是否非法请求等),在写链路的时候,才对库存做一致性检查,在数据层保证最终准确性。

        不同层次尽可能过滤掉无效请求,只在“漏斗” 最末端进行有效处理,从而缩短系统瓶颈的影响路径。

      2. 高并发写

        1. 更换DB选型:换用缓存系统(带有持久化功能的缓存,如Redis,适合减库存操作逻辑单一的,无事务要求的)

        2. 优化DB性能:库存数据落地到数据库实现其实是一行存储(MySQL),因此会有大量线程来竞争 InnoDB 行锁。但并发越高,等待线程就会越多,TPS 下降,RT 上升,吞吐量会受到严重影响。

          两种方法:

          1. 应用层排队。加入分布式锁,控制集群对同一行记录进行操作的并发度,也能控制单个商品占用数据库连接的数量
          2. 数据层排队。(应用层排队是有损性能的,数据层排队是最为理想的。)业界中,阿里的数据库团队开发了针对InnoDB 层上的补丁程序(patch),可以基于DB层对单行记录做并发排队,从而实现秒杀场景下的定制优化。另外阿里的数据库团队还做了很多其他方面的优化,如 COMMIT_ON_SUCCESS 和 ROLLBACK_ON_FAIL 的补丁程序,通过在 SQL 里加入提示(hint),实现事务不需要等待实时提交,而是在数据执行完最后一条 SQL 后,直接根据 TARGET_AFFECT_ROW 的结果进行提交或回滚,减少网络等待的时间(毫秒级)。目前阿里已将包含这些补丁程序的 MySQL 开源:AliSQL。
  3. 高可用

    1. 流量削峰

      1. 答题:通过提升购买的复杂度,达到两个目的:防止作弊&延缓请求。本质是通过在入口层削减流量,从而让系统更好地支撑瞬时峰值。
      2. 排队:最为常见消息队列,通过把同步的直接调用转换成异步的间接推送,缓冲瞬时流量。(弊端:请求积压、用户体验)(排队本质是在业务层将一步操作转变成两步操作,从而起到缓冲的作用,但鉴于此种方式的弊端,最终还是要基于业务量级和秒杀场景做出妥协和平衡。)
      3. 过滤:过滤的核心目的是通过减少无效请求的数据IO 保障有效请求的IO性能。
        1. 读限流:对读请求做限流保护,将超出系统承载能力的请求过滤掉
        2. 读缓存:对读请求做数据缓存,将重复的请求过滤掉
        3. 写限流:对写请求做限流保护,将超出系统承载能力的请求过滤掉
        4. 写校验:对写请求做一致性校验,只保留最终的有效数据
    2. Plan B

      1. 架构阶段:考虑系统的可扩展性和容错性,避免出现单点问题。例如多地单元化部署,即使某个IDC甚至地市出现故障,仍不会影响系统运转

        编码阶段:保证代码的健壮性,例如RPC调用时,设置合理的超时退出机制,防止被其他系统拖垮,同时也要对无法预料的返回错误进行默认的处理

        测试阶段:保证CI的覆盖度以及Sonar的容错率,对基础质量进行二次校验,并定期产出整体质量的趋势报告

        发布阶段:系统部署最容易暴露错误,因此要有前置的checklist模版、中置的上下游周知机制以及后置的回滚机制

        运行阶段:系统多数时间处于运行态,最重要的是运行时的实时监控,及时发现问题、准确报警并能提供详细数据,以便排查问题

        故障发生:首要目标是及时止损,防止影响面扩大,然后定位原因、解决问题,最后恢复服务

      2. 预防:建立常态压测体系,定期对服务进行单点压测以及全链路压测,摸排水位

        管控:做好线上运行的降级、限流和熔断保护。需要注意的是,无论是限流、降级还是熔断,对业务都是有损的,所以在进行操作前,一定要和上下游业务确认好再进行。就拿限流来说,哪些业务可以限、什么情况下限、限流时间多长、什么情况下进行恢复,都要和业务方反复确认

        监控:建立性能基线,记录性能的变化趋势;建立报警体系,发现问题及时预警

        恢复:遇到故障能够及时止损,并提供快速的数据订正工具,不一定要好,但一定要有
        在系统建设的整个生命周期中,每个环节中都可能犯错,甚至有些环节犯的错,后面是无法弥补的或者成本极高的。所以高可用是一个系统工程,必须放到整个生命周期中进行全面考虑。同时,考虑到服务的增长性,高可用更需要长期规划并进行体系化建设。

image-20200525191748562

亿级数据

从千万的数据到亿级的数据,会面临哪些技术挑战?你的技术解决思路?

https://zhuanlan.zhihu.com/p/51081227

最常见的数据库,如MySql、Oracle等,都采用行式存储,比较适合OLTP。如果用MySql等行数据库来实现OLAP,一般都会碰到两个瓶颈:

  1. 数据量瓶颈:mysql比较适合的数据量级是百万级,再多的话,查询和写入性能会明显下降。因此,一般会采用分库分表的方式,把数据规模控制在百万级。
  2. 查询效率瓶颈:mysql对于常用的条件查询,需要单独建立索引或组合索引。非索引字段的查询需要扫描全表,性能下降明显。

分表

垂直业务拆分=分库+微服务(可分库基础上再分表)

https://zhuanlan.zhihu.com/p/54594681

监控

集群监控的时候,重点需要关注哪些技术指标?这些指标如何优化?
  1. 系统指标:cpu使用率、内存使用率、机器连通性、系统负载(cpu.load)
  2. 网络指标:网络流入速度、网络流出速度、网络流入包数、网络流出包数、TCP连接数、TCP Active Opens(主动打开数)、IP接收包数、IP丢包数、TCP接收包数、TCP发送包数、TCP包传输错误数、TCP重传数
  3. 磁盘指标:磁盘使用率、iNode使用率、磁盘繁忙占比、磁盘读速度、磁盘写速度、磁盘读次数、磁盘写次数
  4. 容器指标?:线程数[容器指标]/平均到每核、进程数[容器指标]/平均到每核….

监控知识体系

[小米监控](