2014-12-24 26 views
13

Próbuję zrozumieć elementy wewnętrzne Apache Spark. Zastanawiam się, czy Spark używa pewnych mechanizmów, aby zapewnić lokalność danych podczas odczytu z InputFormat lub zapisu do OutputFormat (lub innych formatów natywnie obsługiwanych przez Spark i nie pochodzących od MapReduce).Czy Spark używa lokalizacji danych?

W pierwszym przypadku (czytanie), moim zrozumieniem jest to, że przy użyciu InputFormat splits są powiązane z hostem (lub hostami ??), które zawierają dane, więc Spark próbuje przypisywać zadania do executorów w celu zmniejszenia transfer sieci w miarę możliwości.

W przypadku pisania, jak taki mechanizm zadziała? Wiem, że technicznie, plik w HDFS może być zapisany w dowolnym węźle lokalnie i replikowany do dwóch pozostałych (więc używasz sieci dla dwóch z 3 replik), ale jeśli rozważasz pisanie do innych systemów, takich jak baza danych NoSQL (Cassandra, HBase, inni ..), takie systemy mają swój własny sposób dystrybucji danych. Czy istnieje sposób, aby powiedzieć iskrowi, aby podzielić RDD w taki sposób, aby zoptymalizować lokalizację danych na podstawie rozkładu danych oczekiwanych przez zlew wyjściowy (docelową bazę danych NoSQL, widziane natywnie lub przez OutputFormat)?

Mam na myśli środowisko, w którym węzły Spark i węzły NoSQL żyją na tych samych maszynach fizycznych.

Odpowiedz

4

Jeśli używasz Spark i Cassandra na tej samej maszynie fizycznej, powinieneś sprawdzić spark-cassandra-connector Zapewni to lokalność danych zarówno do odczytu, jak i zapisu.

Na przykład, jeśli załadujesz tabelę Cassandra do RDD, łącznik zawsze będzie próbował wykonywać operacje na tym RDD lokalnie w każdym węźle. Po zapisaniu RDD w Cassandrze złącze spróbuje również zapisać wyniki lokalnie.

Zakładając, że Twoje dane są już zrównoważone w całym klastrze Cassandra. Jeśli twój klucz PartitionKey nie zostanie poprawnie wykonany, i tak otrzymasz niezbilansowany klaster.

Pamiętaj także o tasowaniu zleceń na urządzeniu Spark. Na przykład, jeśli wykonasz ReduceByKey na RDD, i tak skończysz strumieniować dane w sieci. Dlatego zawsze starannie planuj te prace.

+0

Zgadzam się z większością tego. Jednak ReduceByKey może skorzystać z partycjonowania. Jeśli Twoje RDD jest sparowane (tj. (Klucz, wartość)), możesz zrobić spiredRdd.partitionBy (nowy HashPartitioner (100)), który zachowa informacje o partycjonowaniu. Następnie możesz zrobić ReduceByKey, który skorzysta z informacji o partycjonowaniu i wykona lokalne redukcje. Może to potencjalnie uniknąć kosztów przetasowania/sieci. – ashic

+0

O ile mi wiadomo, lokalizacja zapisu dla złącza iskrobassandra oznacza, że ​​węzeł koordynujący dla operacji zapisu będzie znajdować się na tej samej maszynie co węzeł iskrowy, który uruchamia zadanie zapisu dla danej partycji (LocalNodeFirst ...) . Węzeł koordynatora powinien następnie przekazać operację zapisu do replik ONE/TWO/THREE/XX. Jeśli robię wsadowe zapisywanie ze spójnością JEDNĄ, prawdziwą optymalizacją byłoby organizowanie partycji w taki sposób, że węzeł koordynatora powinien zapisywać dane tylko lokalnie przed wysłaniem OK do konektora. Czy taki scenariusz jest możliwy (Cassandra lub jakikolwiek inny DB)? –

+0

To domyślne zachowanie w partiach Cassandry. Chociaż nie zaleca się używania partii, WriteAsync jest o wiele bardziej zoptymalizowany (szczególnie w sterowniku Java Java). Istnieje również różnica między polityką zapisu a współczynnikiem replikacji w Cassandrze. Jeśli napiszesz do JEDNEGO węzła i użyjesz współczynnika replikacji równego 3, węzeł koordynatora odpowie OK po pomyślnym zapisie dla jednego węzła. Następnie rozpocznie się proces replikacji. Nie trzeba czekać na replikację podczas pisania. – Emam

Powiązane problemy