Page 1
trait Speaker { val name:String val aliases:Set[String]}
trait Organization{ val bu = "tmall" val group = "alibaba"}
object WangFuqiang extends Speaker with Organization{ val name = "王福强"
val aliases = Set("千任", "@囚千任") val blog = “http://afoo.me”}
架构模式与实践漫谈
Sunday, July 14, 13
Page 2
Architecture
Sunday, July 14, 13
Page 3
Architecture Principles• Abstraction
• Modularity
• Scalability
• Robustness
• Security
• Availability
• Reusability
• name it more...
Sunday, July 14, 13
Page 4
Exciting?
Sunday, July 14, 13
Page 5
Don’t Be Silly!
Sunday, July 14, 13
Page 6
Overload
Sunday, July 14, 13
Page 7
How About Practices + Patterns
Sunday, July 14, 13
Page 8
Roadmap First
Sunday, July 14, 13
Page 9
Consistency
Layering
Isolation
Immutability
Clustering
Buffering
Async
Throttling单结点 多结点
Sunday, July 14, 13
Page 10
Sunday, July 14, 13
Page 11
So Far, So Good
Sunday, July 14, 13
Page 12
Consistency
Layering
Caching
Isolation
Immutability
Clustering
Async
Throttling
Sunday, July 14, 13
Page 13
What we do?
Sunday, July 14, 13
Page 14
Sure, 1. Scale Up!
纵向扩展
Sunday, July 14, 13
Page 15
“I try so hard, I got so far...”
‘cause hardware can’t work well without proper software
Sunday, July 14, 13
Page 16
Sunday, July 14, 13
Page 17
Sunday, July 14, 13
Page 18
Buffering缓冲
Sunday, July 14, 13
Page 19
Queuesfucking simple idea, right?
Sunday, July 14, 13
Page 20
Queue Everywhere• cpu task run queue
• thread pool task queue
• actors’ mailbox
• TCP stack send buffer /receive buffer
• MOM
• etc.
Sunday, July 14, 13
Page 21
Batching分批处理when they slowly move
Sunday, July 14, 13
Page 22
Sunday, July 14, 13
Page 23
When to batchWhen to flush
Sunday, July 14, 13
Page 24
Problem With Nagle Algorithm
Sunday, July 14, 13
Page 25
Latency VS.
Throughput
It’s your choice!
Sunday, July 14, 13
Page 26
Smart Batchingfocus on the whole pipeline
Sunday, July 14, 13
Page 27
http://mechanical-sympathy.blogspot.com/2011/10/smart-batching.html
• Lock-free
• 100K+ TPS
Sunday, July 14, 13
Page 28
DisruptorStart 2 use it today
Sunday, July 14, 13
Page 29
--------割--------
Sunday, July 14, 13
Page 30
Sunday, July 14, 13
Page 31
Throttling限流|flow control
Sunday, July 14, 13
Page 32
Rate ControlBackpressure
Sunday, July 14, 13
Page 33
Rate Control
Sunday, July 14, 13
Page 34
Semaphore
Sunday, July 14, 13
Page 35
僵硬 灵活
Sunday, July 14, 13
Page 36
Let’s apply
BackPressureButterfly Effect
Sunday, July 14, 13
Page 37
Sunday, July 14, 13
Page 38
Sunday, July 14, 13
Page 39
Sunday, July 14, 13
Page 40
表征
位置(反馈)方式
what
where how
BackPressure
load, rt, etc.
ack, nack, etc.hardware, os, app, etc.
Sunday, July 14, 13
Page 41
--------割--------
Sunday, July 14, 13
Page 42
2 + 2 = ?
Sunday, July 14, 13
Page 43
Sunday, July 14, 13
Page 44
Sunday, July 14, 13
Page 45
Caching缓存
Sunday, July 14, 13
Page 46
Why Caching?
Sunday, July 14, 13
Page 47
Sunday, July 14, 13
Page 48
Cache Everywhere• CPU Level1-3 cache
• Browser-side cache
• Server-side cache
• Business-layer cache
• DAL-layer cache
• Database-level cache
• Reverse Proxy
• DNS
• Name it more...
Sunday, July 14, 13
Page 49
Cache Types• Local Cache
• Map
• Ehcache * (BigHeap)
• Redis
• Remote Cache
• Tair *
• Memcached
• In-Memory Data Grid - IMDG
• Coherence
• GemFire
* means Hybrid
Sunday, July 14, 13
Page 50
Cache Strategy
Dimension Synchronous Asynchronous
READ Read-Through Refresh-Ahead
WRITE Write-Through Write-Behind
Sunday, July 14, 13
Page 51
Caching Tricks• Dummy Value
• non-exist entities in storage
• Versioning
• long-period-cached files
K1
K2
K3
K1
K2
K3
K4 K4
K5 K5
Cache Storage
file1.v1
file1.v2index.html <=> file1
Sunday, July 14, 13
Page 52
Case Study - 支付宝双11预充值
我爬...
我也爬...
我跟着爬...
我等?!
Sunday, July 14, 13
Page 53
--------割--------
Sunday, July 14, 13
Page 54
Async异步
Sunday, July 14, 13
Page 55
give me the quote of EUR/USD
here u arebuy 2 lots
transaction result
Story Background...
Sunday, July 14, 13
Page 56
Future<Double> rateQuoteFuture = executor.submit(new Callable<Double>() { @Override public Double call() throws Exception { connection.getCurrentValue(USD); } });
try { Double rateQuote = rateQuoteFuture.get(5, TimeUnit.SECONDS); // Blocking wait Future<Integer> future = executor.submit(new Callable<Object>() { @Override public Integer call() throws Exception { if(isProfitable(rateQuote)) connection.buy(amount, rateQuote) else throw new Exception("not profitable"); } }); Integer amount = future.get(5, TimeUnit.SECONDS); // Blocking wait System.out.println("Purchased "+ amount + " USD"); } catch (InterruptedException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (ExecutionException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (TimeoutException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. }
Go Async
Sunday, July 14, 13
Page 57
The Pain In The Neckblocking wait
Sunday, July 14, 13
Page 58
1. val rateQuote = future {2. connection.getCurrentValue(USD)3. }
5. rateQuote onSuccess { case quote =>6. val purchase = future {7. if (isProfitable(quote)) connection.buy(amount, quote)8. else throw new Exception("not profitable")9. }10. 11. purchase onSuccess {12. case _ => println("Purchased " + amount + " USD")13. }14.}
Go Reactive
Sunday, July 14, 13
Page 59
Behind The Pretty Face blocking still exists
Sunday, July 14, 13
Page 60
Task Scheduling Matters
Sunday, July 14, 13
Page 61
Async & Task Schedule Granularity
•Process•Thread•Actor•Coroutine•Continuation
Sunday, July 14, 13
Page 62
Go Non-Blocking
Sunday, July 14, 13
Page 63
And Think In Big Picture
Sunday, July 14, 13
Page 64
Sir, Yes, Sir.Sunday, July 14, 13
Page 65
R All Async Good?
Sunday, July 14, 13
Page 66
“Trade A For A” AsyncAnti-Pattern
Sunday, July 14, 13
Page 67
A yelled ‘get it done’
B working...
A looking/waiting/smoking...
Sunday, July 14, 13
Page 68
Future<Double> rateQuoteFuture = executor.submit(new Callable<Double>() { @Override public Double call() throws Exception { connection.getCurrentValue(USD); } });
Double rateQuote = rateQuoteFuture.get(5, TimeUnit.SECONDS);// Nothing more to do, just wait and return
Sunday, July 14, 13
Page 69
Future<Double> rateQuoteFuture = executor.submit(new Callable<Double>() { @Override public Double call() throws Exception { connection.getCurrentValue(USD); } });
Double rateQuote = rateQuoteFuture.get(5, TimeUnit.SECONDS);// Nothing more to do, just wait and return
Why don’t U do it in current thread?
Sunday, July 14, 13
Page 70
It’s All About
RESOURCE UTILITY资源利用率是关键
Sunday, July 14, 13
Page 71
SEDAA grand master of buffering + async
Sunday, July 14, 13
Page 72
Sunday, July 14, 13
Page 73
--------割--------
Sunday, July 14, 13
Page 74
Sunday, July 14, 13
Page 75
Sunday, July 14, 13
Page 76
Layering
Isolation
Immutability
Clustering
Buffering
Async
ThrottlingManage Dependencies
Wisely明智地管理依赖
Sunday, July 14, 13
Page 77
WhereWeStand Service2
Service1
Service3
Sunday, July 14, 13
Page 78
ExceptionStart Small, But Basic!
Sunday, July 14, 13
Page 79
What we do after catch?retry?
ignore?throw up?
Sunday, July 14, 13
Page 80
Sunday, July 14, 13
Page 81
Sunday, July 14, 13
Page 82
Timeout Everywhere• Thread.join(long)
• Future.get(long, TimeUnit)
• ExecutorService.awaitTermination(long, TimeUnit)
• CountDownLatch.await(long, TimeUnit)
• RPC Framework, say, HSF or Dubbo
• IO timeout
• you name it...
Sunday, July 14, 13
Page 83
Circuit Breaker Pattern
I want it to be automatic!
Sunday, July 14, 13
Page 84
Sunday, July 14, 13
Page 85
Sunday, July 14, 13
Page 86
SwitchesI don’t need you here!
开关
Sunday, July 14, 13
Page 87
Sunday, July 14, 13
Page 88
trait PartialFunction[-A, +B] extends (A => B) { self => import PartialFunction._
/** Checks if a value is contained in the function's domain. * * @param x the value to test * @return `'''true'''`, iff `x` is in the domain of this function, `'''false'''` otherwise. */ def isDefinedAt(x: A): Boolean ...}
trait Function1[@specialized(..) -T1, @specialized(..) +R] extends AnyRef { self => /** Apply the body of this function to the argument. * @return the result of function application. */ def apply(v1: T1): R
http://www.infoq.com/cn/articles/function-switch-realize-better-continuous-implementations
Switch.reduce{
}Sunday, July 14, 13
Page 89
Hard Enough
Sunday, July 14, 13
Page 90
2. Scale Out横向扩展
Sunday, July 14, 13
Page 91
We r gonna Cluster it.
Sunday, July 14, 13
Page 92
Symmetric
Stateful
State
Asymmetric
Stateless
ComputationSunday, July 14, 13
Page 93
Replicas 复制品, 副本
Sunday, July 14, 13
Page 94
Replica means Symmetric
Sunday, July 14, 13
Page 95
When It Goes Stateless
Sunday, July 14, 13
Page 96
Computational Replicas
Sunday, July 14, 13
Page 97
Master-Workers Pattern
Sunday, July 14, 13
Page 98
Sunday, July 14, 13
Page 99
Sunday, July 14, 13
Page 100
Most of the time, Computation and state are so close...
Sunday, July 14, 13
Page 101
State Replicas
Sunday, July 14, 13
Page 102
Read ScalesRedundancy
Sunday, July 14, 13
Page 103
Replication
Sunday, July 14, 13
Page 104
Replication Types• Consistency Concerning Replication
• Synchronous Replication
• Asynchronous Replication
• Bandwidth Concerning Replication
• Intra-IDC Replication
• Inter-IDC Replication
• Other Views...
Sunday, July 14, 13
Page 105
Load-Balancing
Sunday, July 14, 13
Page 106
Sunday, July 14, 13
Page 107
So short? Just Stay with me
Sunday, July 14, 13
Page 108
--------割--------
Sunday, July 14, 13
Page 109
Shards分片,分区aka. Partitioning
Sunday, July 14, 13
Page 110
Write ScalesStorage Scales
Sunday, July 14, 13
Page 111
Routing
Sunday, July 14, 13
Page 112
Lookup Table
Sunday, July 14, 13
Page 113
Hashing
Sunday, July 14, 13
Page 114
Consistent Hashing
Sunday, July 14, 13
Page 115
Sharding Strategy Matters• Capacity Planning
• Capacity Expanding
• State Transferring
• State Access Pattern
• Fault-Tolerance
• etc.
Sunday, July 14, 13
Page 116
L.B. Vs. Routing
Sunday, July 14, 13
Page 117
--------割--------
Sunday, July 14, 13
Page 118
ShitHappens
Sunday, July 14, 13
Page 119
Sunday, July 14, 13
Page 120
Isolation隔离性
Sunday, July 14, 13
Page 121
Bulkhead Pattern
Sunday, July 14, 13
Page 122
Sunday, July 14, 13
Page 123
One Tab, One Process
Sunday, July 14, 13
Page 124
Linux Container
Sunday, July 14, 13
Page 125
Single Box In A Cluster
Sunday, July 14, 13
Page 126
A Whole Cluster Goes Bad...
Sunday, July 14, 13
Page 127
So When you deploy clusters of• Search Service
• HSF/Dubbo Service
• Data Storage Service
• Caching Service(Tair, Redis, memcached...)
• Whatever that’s important or have higher priority, NO Share!
Sunday, July 14, 13
Page 128
What Do U Think?
Sunday, July 14, 13
Page 129
--------割--------
Sunday, July 14, 13
Page 130
Sunday, July 14, 13
Page 131
Redundancy冗余
Sunday, July 14, 13
Page 132
Symmetric Cluster?
Sunday, July 14, 13
Page 133
Symmetric Cluster?
What A Lucky Boy!
Sunday, July 14, 13
Page 134
What About Asymmetric Cluster?
Sunday, July 14, 13
Page 135
BinaryStar Pattern
Sunday, July 14, 13
Page 136
Sunday, July 14, 13
Page 137
--------割--------
Sunday, July 14, 13
Page 138
Way&Style
Sunday, July 14, 13
Page 139
Consistency一致性
Sunday, July 14, 13
Page 140
Why Consistency?
Sunday, July 14, 13
Page 141
Sunday, July 14, 13
Page 142
Sunday, July 14, 13
Page 143
Consistency Everywhere• Religion
• Bible
• Brotherhood initiation
• Psychology
• Gambling
• Debating
• Industry
大众就一款⻋车高尔夫,拍窄点就是菠萝,加个屁股就是新桑塔纳和新捷达,继续拍一拍就是速腾和朗逸、再捏一把就是新宝来,扩大一圈就是新帕萨特,再拍一拍就是迈腾,再加大一圈就是辉腾,拍成方的就是途安,加多三个后座就是夏朗,加高底盘就是途观,再撑大点就是途锐,拍扁就是尚酷,搓圆了就是甲壳虫。
Sunday, July 14, 13
Page 144
Show Time...
Sunday, July 14, 13
Page 145
统一构建原则
Sunday, July 14, 13
Page 146
In Framework Design like Spring
Sunday, July 14, 13
Page 147
-- Haskell is a pure functional language and even the I/O system can't break this purity.
Sunday, July 14, 13
Page 148
Go Consistency When Necessary
Sunday, July 14, 13
Page 149
Layering分层
Sunday, July 14, 13
Page 150
Why Layering?
Sunday, July 14, 13
Page 151
impact
Sunday, July 14, 13
Page 152
Layer Patterns Everywhere
Can U Name More?
Sunday, July 14, 13
Page 153
Cake Pattern
Sunday, July 14, 13
Page 154
Stackable Traits Pattern Decorator Pattern In Scala
Sunday, July 14, 13
Page 155
--------割--------
Sunday, July 14, 13
Page 156
Immutability不变性
Sunday, July 14, 13
Page 157
Sunday, July 14, 13
Page 158
Sunday, July 14, 13
Page 159
Sunday, July 14, 13
Page 160
Persistent Data Structure
Sunday, July 14, 13
Page 161
Familiar?
Sunday, July 14, 13
Page 162
Event Sourcing
Sunday, July 14, 13
Page 163
Capture all changes to an application state as a sequence of events.
Sunday, July 14, 13
Page 164
Real World ES• Binlog, HLog . . .
• Kafka’s Storage Strategy
• MetaQ - Java Clone of Kafka,
• LMAX Platform
• Many home-brew tools
• Ultra Messaging Stream Edition(UMS) - Informatica
• Available Projects/Solutions
• https://github.com/eligosource/eventsourced
• https://github.com/sbtourist/Journal.IO
• https://github.com/fusesource/hawtjournalSunday, July 14, 13
Page 165
案例分析•TMS编辑和发布的并发控制与潜在冲突
•模板中变量名变更的追踪无案底可查
Sunday, July 14, 13
Page 166
Lambda Pattern
Sunday, July 14, 13
Page 167
Does Lambda’s face inspire U?
Sunday, July 14, 13
Page 168
Sunday, July 14, 13
Page 169
Sunday, July 14, 13
Page 170
http://www.infoq.com/presentations/High-Performance-Network-Applications-in-the-Capital-Markets
Todd-Montgomery
Sunday, July 14, 13
Page 171
Sunday, July 14, 13
Page 172
Log VS. JMXYour Opinion?
Sunday, July 14, 13
Page 173
--------割--------
Sunday, July 14, 13
Page 174
ComposabilityYes, This is a principle :0)
组合
Sunday, July 14, 13
Page 175
灵活运用工具的能力比工具质量要重要的多
Sunday, July 14, 13
Page 176
It’sNot The Ending, It’s The Beginning...
Sunday, July 14, 13
Page 177
推荐书目
Sunday, July 14, 13
Page 178
Have Fun & Happy
Sunday, July 14, 13