架构相关 5
缓存种类
CPU缓存、操作系统缓存、数据库缓存、JVM编译缓存
通读缓存(read-through):CDN缓存、代理与反向代理缓存
旁路缓存(cache-aside):前端缓存、应用程序缓存、分布式对象缓存
缓存的关键指标
缓存命中率 – 缓存键集合大小、缓存可使用内存空间、缓存对象生存时间
不适用缓存场景
频繁修改的数据、没有热点的访问
使用缓存需要考虑的问题
数据不一致与脏读、缓存雪崩、缓存预热、缓存穿透
分布式对象缓存:一致性hash算法
Redis VS Memcached
Redis支持复杂的数据结构
Redis支持多路复用异步I/O高性能
Redis支持主从复制高可用
Redis原生集群与share nothing集群模式
消息队列用于构建异步调用架构
点对点模型、发布订阅模型
消息队列架构的优点
1. 可实现异步处理,提升处理性能
2. 更好的伸缩性
3. 削峰填谷
4. 失败隔离和自我修复
5. 解藕
主要MQ产品
Kafka、RabbitMQ、ActiveMQ、RocketMQ
负载均衡架构
DNS负载均衡、反向代理负载均衡、IP负载均衡、数据链路层负载均衡
负载均衡算法
轮询、加权轮询、随机、最少连接、源地址散列
一致性哈希算法的原理与实现
一致性哈希算法的思路为:先构造出一个长度为232整数环,根据N0-3的节点名称的hash值(分布为[0,232-1])放到这个环上。现在要存放资源,根据资源的Key的Hash值(也是分布为[0,232-1])值Haaa,在环上顺时针的找到离Haaa最近(第一个大于或等于Haaa)的一个节点,就建立了资源和节点的映射关系。
1.把机器按照某种hash算法(比如MD5)计算得到机器的hashcode值。
2.对于存储的数据,根据数据的key,使用与机器相同的hash算法获取到相应的hashcode值,然后将key写入到顺时针最近的机器。
3.可以是hashcode(key) <= hashcode(machine)的机器。
4.当有新机器加入时,只需要把新加入机器影响到的数据进行重新分配;当删除机器时,只需要把被删除机器的数据重新分配一下,这样可以减小数据的迁移代价。
5.为了维持平衡性,防止雪崩效应,使用虚拟节点代替真实机器,一个真实机器对应多个虚拟节点,这样可以保证数据的分布均衡。
import hashlib
server_ip_list = ["192.168.1.10", "192.168.2.20", "192.168.3.30","192.168.4.40"]
client_ip_list = ["113.88.97.173", "106.11.154.33", "207.46.13.149","42.156.137.120", "203.208.60.0", "119.39.47.182", "171.34.179.4", "111.175.58.52", "124.235.138.199","175.184.166.184","111.175.58.52", "124.235.18.119","175.144.163.124","175.14.166.114","111.175.8.152", "124.23.18.113","175.144.13.116"]
def get_md5(data):
m = hashlib.md5()
m.update(data.encode('utf-8'))
return m.hexdigest()
def get_ip():
virtual_nodes = 500
node_dict = {}
# 遍历服务器ip,生成对应的虚拟结点
for serverip in server_ip_list:
for i in range(virtual_nodes):
# serverip加上一些动态参数生成md5值
hash_key = get_md5(str('{0}VN{1}'.format(serverip,i)))
node_dict[hash_key]=serverip
# 将node_dict字典按key排序生成列表
sorted_key_list = sorted(node_dict)
# 将node_dict字典按key排序
node_dict = sorted(node_dict.items(),key=lambda d:d[0],reverse=False)
for clientip in client_ip_list:
selected_key_list = []
# clientip生成md5值
hc = get_md5(str(clientip))
#print(hc)
switch = 0
for key in sorted_key_list:
#print(key)
# clientip和sorted_key_list中的md5值做比较,clientip的md5值小于等于sorted_key_list中的md5值,switch=1
if hc <= key:
selected_key_list.append(key)
switch=1
if switch == 0:
firstkey = sorted_key_list[0]
else:
firstkey = selected_key_list[0]
print("{0}请求的服务器ip为:{1}".format(clientip,dict(node_dict)[firstkey]))
# for i in range(2):
get_ip()
评论