Download presentation

Presentation is loading. Please wait.

Published byAllan Bridgers Modified about 1 year ago

1
Piccolo: Building fast distributed programs with partitioned tables Russell Power Jinyang Li New York University

2
Motivating Example: PageRank for each node X in graph: for each edge X Z: next[Z] += curr[X] Repeat until convergence A B,C,D BEBE CDCD … A: 0.12 B: 0.15 C: 0.2 … A: 0 B: 0 C: 0 … CurrNextInput Graph A: 0.2 B: 0.16 C: 0.21 … A: 0.2 B: 0.16 C: 0.21 … A: 0.25 B: 0.17 C: 0.22 … A: 0.25 B: 0.17 C: 0.22 … Fits in memory!

3
PageRank in MapReduce Distributed Storage Graph streamRank stream A->B,C, B->D A:0.1, B:0.2 Rank stream A:0.1, B:0.2 Data flow models do not expose global state.

4
PageRank in MapReduce Distributed Storage Graph streamRank stream A->B,C, B->D A:0.1, B:0.2 Rank stream A:0.1, B:0.2 Data flow models do not expose global state.

5
PageRank With MPI/RPC Distributed Storage Graph A->B,C … Graph A->B,C … Ranks A: 0 … Ranks A: 0 … Graph B->D … Graph B->D … Ranks B: 0 … Ranks B: 0 … Graph C->E,F … Graph C->E,F … Ranks C: 0 … Ranks C: 0 … User explicitly programs communication

6
Piccolo’s Goal: Distributed Shared State Distributed Storage Graph A->B,C B->D … Ranks A: 0 B: 0 … Ranks A: 0 B: 0 … read/write Distributed in- memory state

7
Piccolo’s Goal: Distributed Shared State Graph A->B,C … Graph A->B,C … Ranks A: 0 … Ranks A: 0 … Graph B->D … Graph B->D … Ranks B: 0 … Ranks B: 0 … Graph C->E,F … Graph C->E,F … Ranks C: 0 … Ranks C: 0 … Piccolo runtime handles communication

8
Ease of usePerformance

9

10
Talk outline Motivation Piccolo's Programming Model Runtime Scheduling Evaluation

11
Programming Model Graph A B,C B D … Ranks A: 0 B: 0 … Ranks A: 0 B: 0 … read/write x get/put update/iterate Implemented as library for C++ and Python

12
def main(): for i in range(50): launch_jobs(NUM_MACHINES, pr_kernel, graph, curr, next) swap(curr, next) next.clear() def pr_kernel(graph, curr, next): i = my_instance n = len(graph)/NUM_MACHINES for s in graph[(i-1)*n:i*n] for t in s.out: next[t] += curr[s.id] / len(s.out) Naïve PageRank with Piccolo Run by a single controller Run by a single controller Jobs run by many machines curr = Table(key=PageID, value=double) next = Table(key=PageID, value=double) Controller launches jobs in parallel

13
Naïve PageRank is Slow Graph A->B,C … Graph A->B,C … Ranks A: 0 … Ranks A: 0 … Graph B->D … Graph B->D … Ranks B: 0 … Ranks B: 0 … Graph C->E,F … Graph C->E,F … Ranks C: 0 … Ranks C: 0 … get put get

14
PageRank: Exploiting Locality Control table partitioning Co-locate tables Co-locate execution with table curr = Table(…,partitions=100,partition_by=site) next = Table(…,partitions=100,partition_by=site) group_tables(curr,next,graph) def pr_kernel(graph, curr, next): for s in graph.get_iterator(my_instance) for t in s.out: next[t] += curr[s.id] / len(s.out) def main(): for i in range(50): launch_jobs(curr.num_partitions, pr_kernel, graph, curr, next, locality=curr) swap(curr, next) next.clear()

15
Exploiting Locality Graph A->B,C … Graph A->B,C … Ranks A: 0 … Ranks A: 0 … Graph B->D … Graph B->D … Ranks B: 0 … Ranks B: 0 … Graph C->E,F … Graph C->E,F … Ranks C: 0 … Ranks C: 0 … get put get

16
Exploiting Locality Graph A->B,C … Graph A->B,C … Ranks A: 0 … Ranks A: 0 … Graph B->D … Graph B->D … Ranks B: 0 … Ranks B: 0 … Graph C->E,F … Graph C->E,F … Ranks C: 0 … Ranks C: 0 … put get put get

17
Synchronization Graph A->B,C … Graph A->B,C … Ranks A: 0 … Ranks A: 0 … Graph B->D … Graph B->D … Ranks B: 0 … Ranks B: 0 … Graph C->E,F … Graph C->E,F … Ranks C: 0 … Ranks C: 0 … put (a=0.3) put (a=0.2) How to handle synchronization?

18
Synchronization Primitives Avoid write conflicts with accumulation functions NewValue = Accum(OldValue, Update) sum, product, min, max Global barriers are sufficient Tables provide release consistency

19
PageRank: Efficient Synchronization curr = Table(…,partition_by=site,accumulate=sum) next = Table(…,partition_by=site,accumulate=sum) group_tables(curr,next,graph) def pr_kernel(graph, curr, next): for s in graph.get_iterator(my_instance) for t in s.out: next.update(t, curr.get(s.id)/len(s.out)) def main(): for i in range(50): handle = launch_jobs(curr.num_partitions, pr_kernel, graph, curr, next, locality=curr) barrier(handle) swap(curr, next) next.clear() Accumulation via sum Update invokes accumulation function Explicitly wait between iterations

20
Efficient Synchronization Graph A->B,C … Graph A->B,C … Ranks A: 0 … Ranks A: 0 … Graph B->D … Graph B->D … Ranks B: 0 … Ranks B: 0 … Graph C->E,F … Graph C->E,F … Ranks C: 0 … Ranks C: 0 … put (a=0.3) put (a=0.2) update (a, 0.2) update (a, 0.3) Runtime computes sum Workers buffer updates locally Release consistency Workers buffer updates locally Release consistency

21
Table Consistency Graph A->B,C … Graph A->B,C … Ranks A: 0 … Ranks A: 0 … Graph B->D … Graph B->D … Ranks B: 0 … Ranks B: 0 … Graph C->E,F … Graph C->E,F … Ranks C: 0 … Ranks C: 0 … put (a=0.3) put (a=0.2) update (a, 0.2) update (a, 0.3)

22
PageRank with Checkpointing curr = Table(…,partition_by=site,accumulate=sum) next = Table(…,partition_by=site,accumulate=sum) group_tables(curr,next) def pr_kernel(graph, curr, next): for node in graph.get_iterator(my_instance) for t in s.out: next.update(t,curr.get(s.id)/len(s.out)) def main(): curr, userdata = restore() last = userdata.get(‘iter’, 0) for i in range(last,50): handle = launch_jobs(curr.num_partitions, pr_kernel, graph, curr, next, locality=curr) cp_barrier(handle, tables=(next), userdata={‘iter’:i}) swap(curr, next) next.clear() Restore previous computation User decides which tables to checkpoint and when

23
Distributed Storage Recovery via Checkpointing Graph A->B,C … Graph A->B,C … Ranks A: 0 … Ranks A: 0 … Graph B->D … Graph B->D … Ranks B: 0 … Ranks B: 0 … Graph C->E,F … Graph C->E,F … Ranks C: 0 … Ranks C: 0 … Runtime uses Chandy-Lamport protocol

24
Talk Outline Motivation Piccolo's Programming Model Runtime Scheduling Evaluation

25
Load Balancing master J5 J3 Other workers are updating P6! Pause updates! P1 P1, P2 P3 P3, P4 P5 P5, P6 J1 J1, J2 J3 J3, J4 J6 J5, J6 P6 Coordinates work- stealing

26
Talk Outline Motivation Piccolo's Programming Model System Design Evaluation

27
Piccolo is Fast NYU cluster, 12 nodes, 64 cores 100M-page graph Main Hadoop Overheads: Sorting HDFS Serialization Main Hadoop Overheads: Sorting HDFS Serialization PageRank iteration time (seconds) Hadoop Piccolo

28
Piccolo Scales Well EC2 Cluster - linearly scaled input graph ideal 1 billion page graph PageRank iteration time (seconds)

29
Iterative Applications N-Body Simulation Matrix Multiply Asynchronous Applications Distributed web crawler Other applications No straightforward Hadoop implementation

30
Related Work Data flow MapReduce, Dryad Tuple Spaces Linda, JavaSpaces Distributed Shared Memory CRL, TreadMarks, Munin, Ivy UPC, Titanium

31
Conclusion Distributed shared table model User-specified policies provide for Effective use of locality Efficient synchronization Robust failure recovery

32
Gratuitous Cat Picture I can haz kwestions? Try it out: piccolo.news.cs.nyu.edu

33
Naïve PageRank – Problems! curr = Table(key=PageID, value=double) next = Table(key=PageID, value=double) def pr_kernel(graph, curr, next): i = my_instance n = len(graph)/NUM_MACHINES for s in graph[(i-1)*n:i*n]: for t in s.out: next[t] += curr[s.id] / len(s.out) def main(): for i in range(50): launch_kernel(NUM_MACHINES, pr_kernel, graph, curr, next) swap(curr, next) next.clear() Lots of remote reads! No synchronization!

34
Failure Handling Users decide what and when to checkpoint When to checkpoint? At global barriers Periodically during execution What to checkpoint? Table data (saved automatically by Piccolo) User state (saved/restored via callback)

35
System Overview Store table partitions Process table operations Run kernel threads Store table partitions Process table operations Run kernel threads Assign partitions/kernels Run control thread Assign partitions/kernels Run control thread worker master

36
P1 Partition and Kernel Assignment P1, P2 P3 worker P3, P4 P5 P5, P6 master K1 K1, K2 K3 K3, K4 K6 K5, K6 Initially assign kernels by locality

37
Kernel Execution A A C C B B master Remote reads block execution Remote writes are accumulated locally K5 P1 P1, P2 P3 P3, P4 P5 P5, P6 K1 K1, K2 K3 K3, K4 K6 K5, K6

38
Asynchronous Web Crawler Simple to implement Crawl pages quickly, as they are discovered Saturate 100mb link using 32 workers Simple to implement Crawl pages quickly, as they are discovered Saturate 100mb link using 32 workers

39
Exploiting Locality Explicitly divide tables into partitions Expose partitioning to users Users provide key to partition mapping function Co-locate kernels with table partitions Co-locate partitions of different tables

Similar presentations

© 2016 SlidePlayer.com Inc.

All rights reserved.

Ads by Google