Architectural ¡Pa-erns ¡for ¡High ¡ Anxiety ¡Availability ¡ November ¡2012 ¡ Adrian ¡Cockcro5 ¡ @adrianco ¡#ne7lixcloud ¡#qconsf ¡ h?p://www.linkedin.com/in/adriancockcro5 ¡ @adrianco ¡
The ¡Ne7lix ¡Streaming ¡Service ¡ Now ¡in ¡USA, ¡Canada, ¡LaLn ¡America, ¡ UK, ¡Ireland, ¡Sweden, ¡Denmark, ¡ Norway ¡and ¡Finland ¡ @adrianco ¡
US ¡Non-‑Member ¡Web ¡Site ¡ AdverLsing ¡and ¡MarkeLng ¡Driven ¡ @adrianco ¡
Member ¡Web ¡Site ¡ PersonalizaLon ¡Driven ¡ @adrianco ¡
Streaming ¡Device ¡API ¡ Netflix Ready Devices From: May 2008 To: May 2010 @adrianco ¡
Content ¡Delivery ¡Service ¡ Distributed ¡storage ¡nodes ¡controlled ¡by ¡Ne7lix ¡cloud ¡services ¡ @adrianco ¡
November ¡2012 ¡Traffic ¡ @adrianco ¡
Abstract ¡ • Ne7lix ¡on ¡Cloud ¡– ¡What, ¡Why ¡and ¡When ¡ • Globally ¡Distributed ¡Architecture ¡ • Benchmarks ¡and ¡Scalability ¡ • Open ¡Source ¡Components ¡ • High ¡Anxiety ¡ @adrianco ¡
Blah ¡Blah ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡Blah ¡ (I’m ¡skipping ¡all ¡the ¡cloud ¡intro ¡etc. ¡did ¡that ¡ last ¡year… ¡Ne7lix ¡runs ¡in ¡the ¡cloud, ¡if ¡you ¡ hadn’t ¡figured ¡that ¡out ¡already ¡you ¡aren’t ¡ paying ¡a?enLon ¡and ¡should ¡go ¡read ¡Infoq ¡ and ¡slideshare.net/ne7lix) ¡ @adrianco ¡
Things ¡we ¡don’t ¡do ¡ @adrianco ¡
Things ¡We ¡Do ¡Do… ¡ In ¡producLon ¡ at ¡Ne7lix ¡ • Big ¡Data/Hadoop ¡ 2009 ¡ • AWS ¡Cloud ¡ 2009 ¡ • ApplicaLon ¡Performance ¡Management ¡ 2010 ¡ • Integrated ¡DevOps ¡PracLces ¡ 2010 ¡ • ConLnuous ¡IntegraLon/Delivery ¡ 2010 ¡ • NoSQL, ¡Globally ¡Distributed ¡ 2010 ¡ • Pla7orm ¡as ¡a ¡Service; ¡Micro-‑Services ¡ 2010 ¡ 2011 ¡ • Social ¡coding, ¡open ¡development/github ¡ @adrianco ¡
How ¡Ne7lix ¡Works ¡ Consumer ¡ Electronics ¡ User ¡Data ¡ Web ¡Site ¡or ¡ AWS ¡Cloud ¡ Discovery ¡API ¡ Services ¡ PersonalizaLon ¡ CDN ¡Edge ¡ LocaLons ¡ DRM ¡ Customer ¡Device ¡ Streaming ¡API ¡ (PC, ¡PS3, ¡TV…) ¡ QoS ¡Logging ¡ CDN ¡ Management ¡and ¡ Steering ¡ OpenConnect ¡ CDN ¡Boxes ¡ Content ¡Encoding ¡ @adrianco ¡
Web ¡Server ¡Dependencies ¡Flow ¡ (Home ¡page ¡business ¡transacLon ¡as ¡seen ¡by ¡AppDynamics) ¡ Each ¡icon ¡is ¡three ¡ to ¡a ¡few ¡hundred ¡ instances ¡across ¡ Cassandra ¡ three ¡AWS ¡zones ¡ memcached ¡ Web ¡service ¡ Start ¡Here ¡ S3 ¡bucket ¡ PersonalizaLon ¡movie ¡ group ¡chooser ¡ @adrianco ¡
Component ¡Micro-‑Services ¡ Test ¡With ¡Chaos ¡Monkey, ¡Latency ¡Monkey ¡ @adrianco ¡
Three ¡Balanced ¡Availability ¡Zones ¡ Test ¡with ¡Chaos ¡Gorilla ¡ Load ¡Balancers ¡ Zone ¡A ¡ Zone ¡B ¡ Zone ¡C ¡ Cassandra ¡and ¡Evcache ¡ Cassandra ¡and ¡Evcache ¡ Cassandra ¡and ¡Evcache ¡ Replicas ¡ Replicas ¡ Replicas ¡ @adrianco ¡
Triple ¡Replicated ¡Persistence ¡ Cassandra ¡maintenance ¡affects ¡individual ¡replicas ¡ ¡ Load ¡Balancers ¡ Zone ¡A ¡ Zone ¡B ¡ Zone ¡C ¡ Cassandra ¡and ¡Evcache ¡ Cassandra ¡and ¡Evcache ¡ Cassandra ¡and ¡Evcache ¡ Replicas ¡ Replicas ¡ Replicas ¡ @adrianco ¡
Isolated ¡Regions ¡ US-‑East ¡Load ¡Balancers ¡ EU-‑West ¡Load ¡Balancers ¡ Zone ¡A ¡ Zone ¡B ¡ Zone ¡C ¡ Zone ¡A ¡ Zone ¡B ¡ Zone ¡C ¡ Cassandra ¡Replicas ¡ Cassandra ¡Replicas ¡ Cassandra ¡Replicas ¡ Cassandra ¡Replicas ¡ Cassandra ¡Replicas ¡ Cassandra ¡Replicas ¡ @adrianco ¡
Failure ¡Modes ¡and ¡Effects ¡ Failure ¡Mode ¡ Probability ¡ Mi;ga;on ¡Plan ¡ ApplicaLon ¡Failure ¡ High ¡ AutomaLc ¡degraded ¡response ¡ AWS ¡Region ¡Failure ¡ Low ¡ Wait ¡for ¡region ¡to ¡recover ¡ AWS ¡Zone ¡Failure ¡ Medium ¡ ConLnue ¡to ¡run ¡on ¡2 ¡out ¡of ¡3 ¡zones ¡ Datacenter ¡Failure ¡ Medium ¡ Migrate ¡more ¡funcLons ¡to ¡cloud ¡ Data ¡store ¡failure ¡ Low ¡ Restore ¡from ¡S3 ¡backups ¡ S3 ¡failure ¡ Low ¡ Restore ¡from ¡remote ¡archive ¡ @adrianco ¡
Zone ¡Failure ¡Modes ¡ • Power ¡Outage ¡ – Instances ¡lost, ¡ephemeral ¡state ¡lost ¡ – Clean ¡break ¡and ¡recovery, ¡fail ¡fast, ¡“no ¡route ¡to ¡host” ¡ • Network ¡Outage ¡ – Instances ¡isolated, ¡state ¡inconsistent ¡ – More ¡complex ¡symptoms, ¡recovery ¡issues, ¡transients ¡ • Dependent ¡Service ¡Outage ¡ – Cascading ¡failures, ¡misbehaving ¡instances, ¡human ¡errors ¡ – Confusing ¡symptoms, ¡recovery ¡issues, ¡byzanLne ¡effects ¡ More ¡detail ¡on ¡this ¡topic ¡at ¡AWS ¡Re:Invent ¡later ¡this ¡month… ¡ @adrianco ¡
Cassandra ¡backed ¡Micro-‑Services ¡ A ¡highly ¡scalable, ¡available ¡and ¡ durable ¡deployment ¡pa?ern ¡ @adrianco ¡
Micro-‑Service ¡Pa?ern ¡ One ¡keyspace, ¡replaces ¡a ¡single ¡table ¡or ¡materialized ¡view ¡ Single ¡funcLon ¡Cassandra ¡ Cluster ¡Managed ¡by ¡Priam ¡ Many ¡Different ¡Single-‑FuncLon ¡REST ¡Clients ¡ Between ¡6 ¡and ¡72 ¡nodes ¡ Stateless ¡Data ¡Access ¡REST ¡Service ¡ Astyanax ¡Cassandra ¡Client ¡ OpLonal ¡ Datacenter ¡ Each ¡icon ¡represents ¡a ¡horizontally ¡scaled ¡service ¡of ¡three ¡to ¡ Update ¡Flow ¡ hundreds ¡of ¡instances ¡deployed ¡over ¡three ¡availability ¡zones ¡ Appdynamics ¡Service ¡Flow ¡VisualizaLon ¡ @adrianco ¡
Stateless ¡Micro-‑Service ¡Architecture ¡ Linux ¡Base ¡AMI ¡(CentOS ¡or ¡Ubuntu) ¡ Java ¡(JDK ¡6 ¡or ¡7) ¡ OpLonal ¡ Apache ¡ frontend, ¡ memcached, ¡ non-‑java ¡apps ¡ AppDynamics ¡ Tomcat ¡ appagent ¡ monitoring ¡ Monitoring ¡ Log ¡rotaLon ¡ ApplicaLon ¡war ¡file, ¡base ¡ Healthcheck, ¡status ¡ to ¡S3 ¡ servlet, ¡pla7orm, ¡client ¡ servlets, ¡JMX ¡interface, ¡ GC ¡and ¡thread ¡ AppDynamics ¡ interface ¡jars, ¡Astyanax ¡ Servo ¡autoscale ¡ dump ¡logging ¡ machineagent ¡ Epic/Atlas ¡ ¡ @adrianco ¡
Astyanax ¡ Available ¡at ¡h?p://github.com/ne7lix ¡ • Features ¡ – Complete ¡abstracLon ¡of ¡connecLon ¡pool ¡from ¡RPC ¡protocol ¡ – Fluent ¡Style ¡API ¡ – OperaLon ¡retry ¡with ¡backoff ¡ – Token ¡aware ¡ • Recipes ¡ – Distributed ¡row ¡lock ¡(without ¡zookeeper) ¡ – MulL-‑DC ¡row ¡lock ¡ – Uniqueness ¡constraint ¡ – MulL-‑row ¡uniqueness ¡constraint ¡ – Chunked ¡and ¡mulL-‑threaded ¡large ¡file ¡storage ¡ @adrianco ¡
Astyanax ¡Query ¡Example ¡ Paginate ¡through ¡all ¡columns ¡in ¡a ¡row ¡ ColumnList<String> ¡columns; ¡ int ¡pageize ¡= ¡10; ¡ try ¡{ ¡ ¡ ¡ ¡ ¡RowQuery<String, ¡String> ¡query ¡= ¡keyspace ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡.prepareQuery(CF_STANDARD1) ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡.getKey("A") ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡.setIsPaginaLng() ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡.withColumnRange( new ¡RangeBuilder().setMaxSize(pageize).build()); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ while ¡(!(columns ¡= ¡query.execute().getResult()).isEmpty()) ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ for ¡(Column<String> ¡c ¡: ¡columns) ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡} ¡ } ¡ catch ¡(ConnecLonExcepLon ¡e) ¡{ ¡ } ¡ ¡ ¡ @adrianco ¡
Recommend
More recommend