Aswan&hump

37
阿斯旺与驼峰 阿斯旺与驼峰 hongjiang 2011.7.27 hongjiang 2011.7.27

Transcript of Aswan&hump

Page 1: Aswan&hump

阿斯旺与驼峰阿斯旺与驼峰

hongjiang 2011.7.27hongjiang 2011.7.27

Page 2: Aswan&hump

OfferDetailOfferDetail 访问统计访问统计

► 1) 1) 大数据量:每天大数据量:每天 20002000 万万 PVPV 左右,每周左右,每周 pvpv 超过超过11 亿。去重后亿。去重后 offeroffer 量在量在 5000~70005000~7000 万之间。万之间。

► 2) 2) 离散性:统计连续的离散性:统计连续的 55 周,对访问去重后将近周,对访问去重后将近1.51.5 亿亿 (( 总总 offeroffer 为为 2.42.4 亿亿 )) 。每天有。每天有 80%80% 的的 offeroffer只访问了只访问了 11 次,放大到一周,仍有次,放大到一周,仍有 30%30% 多的多的 offeroffer只被访问只被访问 11 次。次。

► 3) 3) 重叠率不高:以周为单位,第重叠率不高:以周为单位,第 11 周访问过周访问过 offeroffer在第在第 22 周又被访问到的约周又被访问到的约 40~55% 40~55% 之间。之间。

Page 3: Aswan&hump

解决方法解决方法

► 1) 1) 缓存全部没有意义,找热点缓存全部没有意义,找热点

► 2) 2) 即使只缓存热点,想要达到较高的命中即使只缓存热点,想要达到较高的命中

率,也依然要缓存很大量的数据。千万级的率,也依然要缓存很大量的数据。千万级的

数据量,必须采用分布式数据量,必须采用分布式

Page 4: Aswan&hump

思路:冷热交换思路:冷热交换

权重大的排在队首

Head

Head

出队

出队

入队

入队

Page 5: Aswan&hump

AswanAswan 的架构的架构

Client Client Client

Index

Scheduler

Storage Storage Storage StorageStorage

Client Client Client

Index

Page 6: Aswan&hump

服务器端的角色服务器端的角色

► 1) Scheduler: 1) Scheduler: 调度调度 // 配置配置 // 注册中心。事件的中心。注册中心。事件的中心。

并通过一致性哈希来将数据分布在各台并通过一致性哈希来将数据分布在各台 StorageStorage 上上

。。

► 2) Index: 2) Index: 索引服务器,用于定位某个索引服务器,用于定位某个 keykey 存储在存储在

哪个哪个 StorageStorage 上。上。 IndexIndex 可配置单台或多台,上面可配置单台或多台,上面

的数据是一致的。多台主要起到负载均衡的作用。的数据是一致的。多台主要起到负载均衡的作用。

► 3) Storage: 3) Storage: 存储服务器,根据数据权重的变化自存储服务器,根据数据权重的变化自

动调节其级别。动调节其级别。

Page 7: Aswan&hump

客户端客户端

► 与与 memcachedmemcached 的的 clientclient 不同,“轻”客户不同,“轻”客户

端,端, clientclient 知道的很少,服务器端的变化对知道的很少,服务器端的变化对

clientclient 来说是透明的,比如新增来说是透明的,比如新增 // 减少减少

StorageStorage ,对,对 clientclient 来说是无需了解的。来说是无需了解的。

► clientclient 定时从配置中心获取可用的定时从配置中心获取可用的 IndexIndex 列列

表。实现方式同表。实现方式同 napoli napoli

Page 8: Aswan&hump

ClientClient 的一次请求过程的一次请求过程

Client

Index

1) 1) 未命中的情况:未命中的情况:

Storage

Scheduler

1 Query

2 未命中,返回 null

3 发送事件

4 定位并通知

5 更新后反馈

6 更新 Index

Page 9: Aswan&hump

ClientClient 的一次请求过程的一次请求过程

2) Index2) Index 命中命中 , Storage, Storage 未命中的情况:未命中的情况:

ClientIndex

2 命中,返回存储节点

1 Query

Storage

3 Get4 返回location

Val 为空

5 Set

Page 10: Aswan&hump

数据更新的解决数据更新的解决

► 使用使用 napolinapoli 监听变更监听变更

napoliTaskSchedulerremove

Storage Storage Storage

remove

Page 11: Aswan&hump

存储结构存储结构

►借鉴借鉴 RedisRedis 的做法,提供 的做法,提供 K-V, K-Hash, K-K-V, K-Hash, K-ListList等结构等结构

应用场景:应用场景:

1) 1) 页面的异步加载,同一个页面的异步加载,同一个 idid 对应几个对应几个

valuevalue ,可采用,可采用 K-HashK-Hash

2)2) 交易订单数,交易订单数, AA 页面显示页面显示 2020 条,条, BB 页面页面

显示显示 1010 条,可采用 条,可采用 K-ListK-List

Page 12: Aswan&hump

通讯框架的选择通讯框架的选择

1, 1, 序列化序列化

1) protocolBuffers:1) protocolBuffers: 不适宜在现有业务上采用。不适宜在现有业务上采用。

2) json/hessian: 2) json/hessian: 性价比未必高性价比未必高

3) Thrift : 3) Thrift : 想采用,但不熟悉想采用,但不熟悉

4) 4) 现在采用 现在采用 java serialize + gzip java serialize + gzip 以后再优化以后再优化

这里有一个详细的对比:这里有一个详细的对比:

https://github.com/eishay/jvm-serializershttps://github.com/eishay/jvm-serializers反馈给温少后,他很快对反馈给温少后,他很快对 fastjsonfastjson 做了优化,后又根做了优化,后又根据江航的建议采用据江航的建议采用 asmasm 优化,最优化,最 1.1.11.1.1 版版 fastjsonfastjson已经超过了已经超过了 protoBuffersprotoBuffers

Page 13: Aswan&hump

通讯框架的选择通讯框架的选择2, 2, 通讯协议通讯协议

1) mina/netty : 1) mina/netty : 缺乏缺乏 NIONIO网络编程的经验,其中的网络编程的经验,其中的陷阱也不少。陷阱也不少。http://www.slideshare.net/killme2008/nio-trick-and-trap-8464155http://www.slideshare.net/killme2008/nio-trick-and-trap-8464155

2) tb-remoting: dubbo2) tb-remoting: dubbo 最初采用的。基于最初采用的。基于 minamina ,,后来后来 dubbodubbo开发了自己开发了自己 dubbo-remotingdubbo-remoting 通讯框架通讯框架,基于,基于 netty3netty3 ,但在写,但在写 AswanAswan 时还没有发布。时还没有发布。

3) http: 3) http: 采用嵌入式采用嵌入式 jettyjetty 用于用于 httphttp 连接管理。简连接管理。简单,但单,但 httphttp 在并发较高时衰减的较快,性能不佳。在并发较高时衰减的较快,性能不佳。

Page 14: Aswan&hump

JettyJetty 的调优的调优

► 1) 1) 增加增加 jetty.acceptorsjetty.acceptors 以应对高并发以应对高并发 使用使用 apache ab 50apache ab 50 并发测试,并发测试, acceptors=8acceptors=8 比比 22 有有明显提高明显提高

httphttp 在并发情况下的衰减在并发情况下的衰减 (acceptors=2) :(acceptors=2) : 11 个线程个线程 httphttp耗时平均耗时平均 1.7ms1.7ms 左右,左右, 1010 个线程并发将衰减到个线程并发将衰减到 5ms5ms 左右,左右, 2020 个线程并发将衰减到个线程并发将衰减到 10ms10ms ,, 5050 个线程降到个线程降到 20ms20ms

Page 15: Aswan&hump

JettyJetty 的调优的调优

► 2) Http-KeepAlive2) Http-KeepAlive 是否起了作用?是否起了作用?

开启 keepAlive , SelectChannelEndPoint 的实例数应该是较稳定的。

Page 16: Aswan&hump

EventQueue

EventQueue

BlockingQueue

IndexServer

Scheduler

事件过程事件过程 : : 上上 ->->下下

消费端

单线程串行通知

Storage

多线程

Page 17: Aswan&hump

事件过程事件过程 : : 上上 ->->下下

EventQueue BlockingQueue

IndexServer Scheduler

生产者缓冲区

消费者缓冲区

Storage: ChangeRecorder

Exchanger :达到一定量再消费

消费者:

单线程

消费者:

单线程

Page 18: Aswan&hump

事件过程事件过程 : : 下下 ->-> 上上Storage

Exchanger

异 步 Exchanger

Index

Index

多线程

单线程串行通知

Exchanger

Exchanger

Scheduler

Page 19: Aswan&hump

事件队列事件队列

►借鉴 借鉴 AWTAWT 中的中的 EventQueue EventQueue com.alibaba.aswan.server.index.WeightingChangeEventQueue.javacom.alibaba.aswan.server.index.WeightingChangeEventQueue.java

► 事件的合并:事件的合并: coalesceEventcoalesceEvent ,对于离散事,对于离散事

件意义不大。件意义不大。

► 锁分离: 两把锁,锁分离: 两把锁, putlockputlock和和 tacklocktacklock 参考参考 LinkedBlockingQueueLinkedBlockingQueue

Page 20: Aswan&hump

缓冲区的设计缓冲区的设计

Exchanger : Exchanger : 简单好用。需考虑缓冲区的大小。生产简单好用。需考虑缓冲区的大小。生产

者的节奏与消费者的节奏是否匹配的上。者的节奏与消费者的节奏是否匹配的上。

Queue: Queue: 需考虑批量消费的需求。自实现批量出列,需考虑批量消费的需求。自实现批量出列,

或者单个出列后累计一定量再一并处理。如果是或者单个出列后累计一定量再一并处理。如果是

BlockingQueueBlockingQueue 注意初始容量,太小会导致高并发注意初始容量,太小会导致高并发

情况下生产者阻塞。进而可能引起网络阻塞等连锁情况下生产者阻塞。进而可能引起网络阻塞等连锁

反应。反应。 AswanAswan 在第一个测试版本遇到过。在第一个测试版本遇到过。

Page 21: Aswan&hump

一致性哈希的选择一致性哈希的选择

►Ketama Ketama 通过通过 MD5MD5 实现实现

last.fmlast.fm 最早采用,最早采用, spy/xmemcachedspy/xmemcached 等等

clientclient 也采用。也采用。

测试中发现测试中发现 240240 个虚拟节点最佳。个虚拟节点最佳。

see: com.alibaba.aswan.server.schedule.locator.KetamaLocator.javasee: com.alibaba.aswan.server.schedule.locator.KetamaLocator.java

►MurmurHashMurmurHash ,更高效的,更高效的 HashHash ,, RedisRedis 的的

java-clientjava-client 中采用中采用

Page 22: Aswan&hump

权重因素权重因素

► 1) 1) 访问次数: 越多越好访问次数: 越多越好► 2) 2) 最后访问事件:越近越好最后访问事件:越近越好

权重公式:权重公式:权重值 权重值 = = 访问次数 访问次数 * * 系数系数

系数与最后访问时间有关,越近系数越高:系数与最后访问时间有关,越近系数越高:

系数公式:系数公式: Math.pow(WEEK_FACTOR, lastAccTime - startTime)Math.pow(WEEK_FACTOR, lastAccTime - startTime)

// week_factor // week_factor 是一个经验值是一个经验值

public static final float WEEK_FACTOR = 1.35F public static final float WEEK_FACTOR = 1.35F

Page 23: Aswan&hump

权重因素权重因素

►3) 3) 增加优先级属性,某些过大的对象优先增加优先级属性,某些过大的对象优先

级设置低一些,比如大于级设置低一些,比如大于 1m1m 的只能沦为二的只能沦为二

等公民,不能存储在等公民,不能存储在 L1L1 中中

Page 24: Aswan&hump

StorageStorage 的内部结构的内部结构

ColdPool L2Val 存在磁盘

L1Val 存在内存

Swap Swap

Page 25: Aswan&hump

双向队列的实现 双向队列的实现

DoubleEndedPriorityQueueDoubleEndedPriorityQueue

2

5

6

4

7

7

6

5

2

4

Min heap Max heap

http://www.cise.ufl.edu/~sahni/dsaaj/enrich/c13/double.htm

维持 2 个 heap,minheap和maxheap

Page 26: Aswan&hump

性能的考虑性能的考虑

► 1) 1) 千万级对象,需要分成很多个区域千万级对象,需要分成很多个区域

否则同步问题成了瓶颈,参考否则同步问题成了瓶颈,参考ConcurrentHashMapConcurrentHashMap 的做法,每的做法,每 11 万个元素存储在万个元素存储在一个一个 Segment Segment 上上

► 2) 2) 避免频繁的堆排序,堆中元素改变超过一个阈值避免频繁的堆排序,堆中元素改变超过一个阈值再进行重排序。再进行重排序。

► 3) 3) 双向堆注意关联影响,对双向堆注意关联影响,对 referentreferent 做一层包装,做一层包装,清除元素时避免引起堆的调整清除元素时避免引起堆的调整 ,,手动排序。手动排序。

Page 27: Aswan&hump

GCGC策略与内存调优策略与内存调优

对象太大,采用对象太大,采用 GzipGzip压缩后平均每个线上压缩后平均每个线上

的的 OfferDOOfferDO 对象对象 5.5k (detail5.5k (detail字段占了大字段占了大

头头 ))

Page 28: Aswan&hump

吞吐量优先还是应用响应优先吞吐量优先还是应用响应优先

► UseParallelOldGC or CMS or G1 ?UseParallelOldGC or CMS or G1 ?

► 一次一次 Full GCFull GC 的代价?的代价? 旧生代的空间有 旧生代的空间有 3.5G3.5G

Page 29: Aswan&hump

按代按代 GCGC策略的组合方式策略的组合方式

http://blogs.oracle.com/jonthecollector/entry/our_collectors

Page 30: Aswan&hump

线上前台应用的线上前台应用的 GCGC策略策略

以以 Exodus2Exodus2 为例: 为例: -server -Xmx2g -Xms2g -Xmn512m -server -Xmx2g -Xms2g -Xmn512m -XX:PermSize=128m -XX:MaxPermSize=196m -Xss256k -XX:PermSize=128m -XX:MaxPermSize=196m -Xss256k -XX:+DisableExplicitGC //-XX:+DisableExplicitGC //禁止外部应用程序强制进行垃圾收集禁止外部应用程序强制进行垃圾收集 ,,

将将 System.gc()System.gc() 调用转换成一个空操作调用转换成一个空操作

-XX:+UseConcMarkSweepGC //-XX:+UseConcMarkSweepGC //启用启用 CMSCMS -XX:+CMSParallelRemarkEnabled // -XX:+CMSParallelRemarkEnabled // 尽量减少 尽量减少 mark mark 的时间 的时间

-XX:+UseCMSCompactAtFullCollection //-XX:+UseCMSCompactAtFullCollection // 对对 live objectlive object进行整理,使进行整理,使memorymemory碎片减少碎片减少

-XX:+UseFastAccessorMethods //-XX:+UseFastAccessorMethods // 对对 getget、、 setset 方法转成本地代码 方法转成本地代码

-XX:+UseCMSInitiatingOccupancyOnly //-XX:+UseCMSInitiatingOccupancyOnly // 只有在只有在 old generationold generation 在达到初在达到初始化的比例后启动收集 始化的比例后启动收集

-XX:+UseCompressedOops //-XX:+UseCompressedOops //压缩普通对象指针,针对压缩普通对象指针,针对 6464 位系统位系统

Page 31: Aswan&hump

► 默认老年代到默认老年代到 92%92%才进行才进行 GC GC (一些老版(一些老版

本的本的 JVMJVM 是是 68%68%))

►可通过 可通过

-XX:CMSInitiatingOccupancyFraction=80-XX:CMSInitiatingOccupancyFraction=80指定为指定为 80%80% 时进行时进行

Page 32: Aswan&hump

精简精简 HashMapHashMap

►HashMapHashMap 中的中的 EntryEntry 存在浪费存在浪费

►修改修改 HashMapHashMap ,实现一个,实现一个 MyHashMapMyHashMap将其初始容量与增长因子设的紧凑一些将其初始容量与增长因子设的紧凑一些

►千万对象,内存节省了约千万对象,内存节省了约 300m300m

Page 33: Aswan&hump

架构的缺陷架构的缺陷

► 1) 1) 角色较多角色较多

► 2) 22) 2 次网络访问,比次网络访问,比 memcachedmemcached 等多一次等多一次

网络开销。网络开销。

► 3) 3) 想要做到想要做到 serverserver 端透明的增减服务器,端透明的增减服务器,

但实际这种需求不强烈。但实际这种需求不强烈。

► 4) hump4) hump ,一个简化版的热点,一个简化版的热点 cachecache ,将采,将采

用用 dubbo-remoting/fastjsondubbo-remoting/fastjson ,类似,类似

memcachedmemcached 方式。包含 方式。包含 K-List, K-Hash K-List, K-Hash 等等存储结构。存储结构。

Page 34: Aswan&hump

分布式领域的一些技术分布式领域的一些技术

► GossipGossip协议协议 : : 去中心化去中心化

又被称为反熵(又被称为反熵( Anti-EntropyAnti-Entropy),反熵就是在杂),反熵就是在杂

乱无章中寻求一致乱无章中寻求一致

GossipGossip 的特点:在一个有界网络中,每个节点都随的特点:在一个有界网络中,每个节点都随

机地与其他节点通信,经过一番杂乱无章的通信,机地与其他节点通信,经过一番杂乱无章的通信,

最终所有节点的状态都会达成一致。每个节点可能最终所有节点的状态都会达成一致。每个节点可能

知道所有其他节点,也可能仅知道几个邻居节点,知道所有其他节点,也可能仅知道几个邻居节点,

只要这些节可以通过网络连通,最终他们的状态都只要这些节可以通过网络连通,最终他们的状态都

是一致的,这也是疫情传播的特点。是一致的,这也是疫情传播的特点。

Page 35: Aswan&hump

分布式领域的一些技术分布式领域的一些技术

GossipGossip 的案例的案例 ::

► Cassandra Cassandra

► RedisRedis 的分布式实现草案。的分布式实现草案。

http://redis.io/presentation/Redis_Cluster.pdfhttp://redis.io/presentation/Redis_Cluster.pdf

Page 36: Aswan&hump

分布式领域的一些技术分布式领域的一些技术

► PaxosPaxos算法算法 : : 解决数据一致性。解决数据一致性。

算法比较复杂。算法比较复杂。

Yahoo!Yahoo!开源的开源的 ZooKeeper ZooKeeper 是一个开源的类是一个开源的类

PaxosPaxos 实现实现

Google Chubby Google Chubby 也基于也基于 paxospaxos算法算法

Page 37: Aswan&hump

参考参考

► <<<< 面向模式的软件架构 面向模式的软件架构 -- 第第 44卷卷 : : 分布式分布式

计算的模式语言计算的模式语言 >>>>

► Napoli ClientNapoli Client

► Jedis Jedis https://github.com/xetorthio/jedis.githttps://github.com/xetorthio/jedis.git RedisRedis 的一个的一个 javajava 客户端客户端