您当前的位置: 首页 >  微服务

zmc@

暂无认证

  • 0浏览

    0关注

    142博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

权衡问题---学习了微服务各大常用组件的一点思考

zmc@ 发布时间:2020-06-11 16:01:16 ,浏览量:0

1.没有什么技术可以完全通用,只要深度使用一定需要从业务出发对技术进行权衡

从几个例子出发:

1.ES的分片机制天生支持分布式,同时也带来了分布式了弊端:排序和算分问题;

搜索的场景需要严格的定制化,通过对mapping的修改可以支持算分的调整,影响查询的结果-----代价是大大增加开发和mapping的维护成本

想要精确的算分和排序--->需要大量的计算和内存

如果数据量不大---->默认使用一个分片---->不需要对排序和算法另外处理/同时牺牲了分布式的特性(建议一个业务场景的分片不超过20g。日志索引的分片不超过50g),这也是为什么7.x版本之后默认一个分片

如果数据量巨大---->必须使用分片----->定制化mapping,粒度到字段级别----->同时还需要大量的内存(只能通过优化尽量压缩,对业务进行区分,必要的时候只能占用大量的cpu和内存 DFS query then Fetch)

 

 

下面来看一下ES的查询过程:默认场景下的-----牺牲精准度保证效率

 

 

 

 

 

2.kafka与ES面临相同的问题:kafka的单个分区内可以保证顺序性,分区之间是不能保证顺序性的

如果是类似于日志,不需要考虑消息的顺序性,那可以很好的发挥性能

 

如果需要保证顺序性:

2.1)从业务上把需要有序的打到同一个partition。因为大多数情况只需要业务上保证有序就可以,不用全局有序(通过message key来定义,因为同一个key的message可以保证只发送到同一个partition,比如说key是user id,table row id等等,所以同一个user或者同一个record的消息永远只会发送到同一个partition上,保证了同一个user或record的顺序)

 

那么单个分片内kafka如何保证有序?

  1. producer发消息到队列时,通过加锁保证有序 现在假设两个问题: broker leader在给producer发送ack时,因网络原因超时,那么Producer 将重试,造成消息重复。 先后两条消息发送。t1时刻msg1发送失败,msg2发送成功,t2时刻msg1重试后发送成功。造成乱序。

     2.解决重试机制引起的消息乱序

       为实现Producer的幂等性,Kafka引入了Producer ID(即PID)和Sequence Number。对于每个PID,该Producer发送消息的每个都对应一个单调递增的Sequence Number。同样,Broker端也会为每个维护一个序号,并且每Commit一条消息时将其对应序号递增。对于接收的每条消息,如果其序号比Broker维护的序号)大一,则Broker会接受它,否则将其丢弃:

  • 如果消息序号比Broker维护的序号差值比一大,说明中间有数据尚未写入,即乱序,此时Broker拒绝该消息,Producer抛出InvalidSequenceNumber
  • 如果消息序号小于等于Broker维护的序号,说明该消息已被保存,即为重复消息,Broker直接丢弃该消息,Producer抛出DuplicateSequenceNumber
  • Sender发送失败后会重试,这样可以保证每个消息都被发送到broker

 

 

3.分布式的系统中路由算法的弊端:增加/删除节点时会有路由错误的问题(引发类似于缓存雪崩的场景)

对应的解决方案:

3.1)如redis的一致性hash算法

3.2)ES同样面临类似的场景:每个index的主分片设置策略,动态分配会有大量的数据迁移,分配不合理又会影响性能

对此,ES的解决方案是:index建立好之后不允重新设置分片,需要重新设置需要reindex

 

2.从CAP到BASE,都是对分布式的一种权衡策略

 

 

总结:

根据不同的需求和场景,进行定制化的使用

 

 

 

 

 

关注
打赏
1643271353
查看更多评论
立即登录/注册

微信扫码登录

0.6233s