zhangll00 2020-01-23
1.分布式服务框架
如果要让不同的子系统或者服务之间互相通信,首先必须有一套分布式服务框架。 也就是各个服务可以互相感知到对方在哪里,可以发送请求过去,可以通过HTTP或者RPC的方式。 在这里,最常见的技术就是dubbo以及spring cloud,当然大厂一般都是自己有服务框架。
2.分布式事务
一旦你的系统拆分为了多个子系统之后,那么一个贯穿全局的分布式事务应该怎么来实现? 这个你需要了解TCC、最终一致性、2PC等分布式事务的实现方案和开源技术。
3.分布式锁 不同的系统之间如果需要在全局加锁获取某个资源的锁定,此时应该怎么来做? 毕竟大家不是在一个JVM里了,不可能用synchronized来在多个子系统之间实现锁吧,是不是?
4.分布式缓存 如果你原来就是个单块系统,那么你其实是可以在单个JVM里进行本地缓存就可以了,比如搞一个HashMap来缓存一些数据。 但是现在你有很多个子系统,他们如果要共享一个缓存,你应该怎么办?是不是需要引入Redis等缓存系统?
5.分布式消息系统 在单块系统内,就一个JVM进程内部,你可以用类似LinkedList之类的数据结构作为一个本地内存里的队列。 但是多个子系统之间要进行消息队列的传递呢?那是不是要引入类似RabbitMQ之类的分布式消息中间件?
6.分布式搜索系统 如果在单块系统内,你可以比如在本地就基于Lucene来开发一个全文检索模块,但是如果是分布式系统下的很多子系统,你还能直接基于Lucene吗? 明显不行,你需要在系统里引入一个外部的分布式搜索系统,比如Elasticsearch。
7.其他很多的技术 分布式配置中心、分布式日志中心、分布式监控告警中心、分布式会话,等等,都是分布式系统场景下你需要使用和了解的一些技术。
场景:假设我们有一个网站,最近发现随着流量增加,服务器压力越来越大,之前直接读写数据库的方式不太给力了,于是我们想引入Memcached作为缓存机制。 解决方案:
1.请求随机
缺点:同一份数据可能被存在不同的机器上而造成数据冗余;有可能某数据已经被缓存但是访问却没有命中,因为无法保证对相同key的所有访问都被发送到相同的服务器。
2.计算哈希
其中Hash是一个从字符串到正整数的哈希映射函数。这样,如果我们将Memcached Server分别编号为0、1、2,那么就可以根据上式和key计算出服务器编号h,然后去访问。
缺点:容错性和扩展性不好:因此系统中一旦有服务器变更,大量的key会被重定位到不同的服务器从而造成大量的缓存不命中。而这种情况在分布式系统中是非常糟糕的。
3.改进优化:一致性哈希
将整个哈希值空间组织成一个虚拟的圆环,如假设某哈希函数H的值空间为0-2^32-1 (即哈希值是一个32位无符号整形)。将数据key使用相同的函数H计算出哈希值h,通根据h确定此数据在环上的位置,从此位置沿环顺时针“行走”,第一台遇到的服务器就是其应该定位到的服务器。
优点:降低受影响的机器。一致性哈希算法对于节点的增减都只需重定位环空间中的一小部分数据,具有较好的容错性和可扩展性。 缺点:一致性哈希算法在服务节点太少时,容易因为节点分部不均匀而造成数据倾斜问题。
4.设置虚拟节点
通常将虚拟节点数设置为32甚至更大,因此即使很少的服务节点也能做到相对均匀的数据分布。