SlideShare ist ein Scribd-Unternehmen logo
1 von 92
Мифы о Спарке
Евгений Борисов
О себе
• Пишу на джаве с 2001
• Преподаю джаву с 2003
• Консультирую с 2008
• Арихтектор с 2009
• Пилю стартап с 2014
• Техлид по биг дате с 2015
• Naya technologies c 2015
Опровержение мифов
• Концептуальные мифы
• Spark это какая то хрень для Hadoop-a
• Spark надо писать на скале
• Spark и Spring не совместимы, и вообще там всё по другому
• Для Spark-а нельзя сложно писать unit тесты
• Технические мифы
• Broadcast – это не только для перформэнса
• Датафрэймы можно использовать только для файлов со схемой
• Главный миф
Главный миф:
Pink Floyd это вам не Бритни Спирс или
Кэтти Пери
Миф первый о Spark-e и Hadoop-e
Что вообще мы знаем про Hadoop
Говно ваш Hadoop
Да да, это тот же человек
И при чём тут Hadoop?
Spark
• Развитие
• Идея зародилась в UC Berkeley примерно в 2009
• Первый релиз в 2012
• Сегодня 1.6 с января 2016
• Spark 2.0 – скоро
• Написан на скале
• Есть API для
• Scala, Python, Java, Java 8, R
• Где писать
• InteliJ, Eclipse, Spark-shell, Notebooks
• Запускать
• Spark-Shell, Notebooks, Spark-submit
• Как обычную Джаву
• Что нужно чтобы можно было запускать на кластере
• Какой-нибудь cluster manager
Cluster manager
• Yarn
• Mesos
Spark with yarn Очень важно!
Часть кода исполняется на кластере
Часть исполняется на драйвере
RDD
Resilient Distributed Dataset
+-Stream
Как можно получить RDD?
• Из файла (файлов в директории)
• Из памяти (обычно используется для тестов)
• Из другого RDD (ну да да, как Стримы)
// from local file system
JavaRDD<String> rdd = sc.textFile("file:/home/data/data.txt");
// from Hadoop using relative path of user, who run spark
application
rdd = sc.textFile("/data/data.txt")
// from hadoop
rdd = sc.textFile("hdfs://data/data.txt")
// all files from directory
rdd = sc.textFile("s3://data/*")
// all txt files from directory
rdd = sc.textFile("s3://data/*.txt")
Из файла / директории
Из памяти
А что это за sc?
• SparkContext / JavaSparkContext
• Main entry point for Spark functionality
SparkConf conf = new SparkConf();
conf.setAppName("my spark application");
conf.setMaster("local[*]");
JavaSparkContext sc = new JavaSparkContext(conf);
Spark Context локально и продакшн
@Bean
@Profile("LOCAL")
public JavaSparkContext sc() {
SparkConf conf = new SparkConf();
conf.setAppName("music analyst");
conf.setMaster("local[1]");
return new JavaSparkContext(conf);
}
@Bean
@Profile("PROD")
public JavaSparkContext sc() {
SparkConf conf = new SparkConf();
conf.setAppName("music analyst");
return new JavaSparkContext(conf);
}
Transformations
• map
• flatMap
• filter
• mapPartitions, mapPartitionsWithIndex
• sample
• union, intersection, join, cogroup, cartesian (otherDataset)
• distinct
• reduceByKey, aggregateByKey, sortByKey
• pipe
• coalesce, repartition, repartitionAndSortWithinPartitions
Actions
• reduce
• collect
• count, countByKey, countByValue
• first
• take, takeSample, takeOrdered
• saveAsTextFile, saveAsSequenceFile, saveAsObjectFile
• foreach
Rdd flow
RDD1Data transformation transformationRDD2 actionRDD3 Benefit
Выполняется на кластере
Да да, это всё Lazy как в стримах
Benefit
RDD1Data RDD2 RDD3 RDD4
RDD5
Benefit
RDD6
Performance trouble
10 минут
10 + 1 + 1 = 12 ?
Benefit
RDD1Data RDD2 RDD3 RDD4
RDD5
Benefit
RDD6
Performance trouble
10 минут
10 + 1 + 1 = 22 !
(10 х 2)
Benefit
RDD1Data RDD2 RDD3 RDD4
RDD5
Benefit
RDD6
collect
Что бы мы сделали в стримах?
Вытащить в коллекцию, а
потом создавать стрим из неё
тоже так пробовали
Out of memory
Benefit
RDD1Data RDD2 RDD3 RDD4
RDD5
Benefit
RDD6
persist
Что умеет Spark
На чём будем писать?
• Scala
• Java
• Python
• R
Что думает о Скале обычный Java developer
продвинутый
Что думает о Скале обычный Java developer
val lines = sc.textFile("data.txt")
val lineLengths = lines.map(_.length)
val totalLength = lineLengths.reduce(_+_)
JavaRDD<String> lines = sc.textFile("data.txt");
JavaRDD<Integer> lineLengths = lines.map(new Function<String, Integer>() {
@Override
public Integer call(String lines) throws Exception {
return lines.length();
}
});
Integer totalLength = lineLengths.reduce(new Function2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer a, Integer b) throws Exception {
return a + b;
}
});
Scala
Java
Говно ваша JAVA
Все персонажи вымышлены,
любое сходство с реальными людьми случайно!
val lines = sc.textFile("data.txt")
val lineLengths = lines.map(_.length)
val totalLength = lineLengths.reduce(_+_)
Scala
Java 8JavaRDD<String> lines = sc.textFile("data.txt");
JavaRDD<Integer> lineLengths = lines.map(String::length);
int totalLength = lineLengths.reduce((a, b) -> a + b);
Миф второй – Spark надо писать на Скале
За Скалу За Джаву
Скала это круто
Миф второй – Spark надо писать на Скале
За Скалу За Джаву
Скала это круто Большинство джава программистов знает джаву
Миф второй – Spark надо писать на Скале
За Скалу За Джаву
Скала это круто Большинство джава программистов знает джаву
Более лаконичный и удобный синтаксис
Миф второй – Spark надо писать на Скале
За Скалу За Джаву
Скала это круто Большинство джава программистов знает джаву
Более лаконичный и удобный синтаксис Знакомый нам мир (Spring, шаблоны проектирования)
Миф второй – Spark надо писать на Скале
За Скалу За Джаву
Скала это круто Большинство джава программистов знает джаву
Более лаконичный и удобный синтаксис Знакомый нам мир (Spring, шаблоны проектирования)
Spark API заточен под Скалу в первую очередь
Миф второй – Spark надо писать на Скале
За Скалу За Джаву
Скала это круто Большинство джава программистов знает джаву
Более лаконичный и удобный синтаксис Знакомый нам мир (Spring, шаблоны проектирования)
Spark API заточен под Скалу в первую очередь
Миф второй – Spark надо писать на Скале
За Скалу За Джаву
Скала это круто Большинство джава программистов знает джаву
Более лаконичный и удобный синтаксис Знакомый нам мир (Spring, шаблоны проектирования)
Spark API заточен под Скалу в первую очередь
Java API выходит чуть позже, и не всегда всё есть
Миф второй – Spark надо писать на Скале
За Скалу За Джаву
Скала это круто Большинство джава программистов знает джаву
Более лаконичный и удобный синтаксис Знакомый нам мир (Spring, шаблоны проектирования)
Spark API заточен под Скалу в первую очередь Большинство джава программистов знает джаву
Java API выходит чуть позже, и не всегда всё есть Знакомый нам мир (Spring, шаблоны проектирования)
Чем будем крыть?
Миф третий
• Spark и Spring не совместимы, и вообще там всё по другому
Давайте уже код писать
Shared data
• Или миф следующий – есть такие случаи когда без broadcasta не
будет работать
Пример
Israel, +9725423632
Israel, +9725454232
Israel, +9721454232
Israel, +9721454232
Spain, +34441323432
Spain, +34441323432
Israel, +9725423232
Israel, +9725423232
Spain, +34441323432
Russia, +78123343434
Russia, +78123343434
Пример
Israel, +9725423632
Israel, +9725454232
Israel, +9721454232
Israel, +9721454232
Spain, +34441323432
Spain, +34441323432
Israel, +9725423232
Israel, +9725423232
Spain, +34441323432
Russia, +78123343434
Russia, +78123343434
Пример
Israel, Orange
Israel, Orange
Israel, Pelephone
Israel, Pelephone
Israel, Hot Mobile
Israel, Orange
Russia, Megaphone
Russia, MTC
Пример
Orange
Orange
Pelephone
Pelephone
Hot Mobile
Orange
Megaphone
MTC
Пример
Israel, +9725423632
Israel, +9725454232
Israel, +9721454232
Israel, +9721454232
Spain, +34441323432
Spain, +34441323432
Israel, +9725423232
Israel, +9725423232
Spain, +34441323432
Russia, +78123343434
Russia, +78123343434
public interface CommonConfig {
Operator getOperator(String phone);
List<String> countries();
}
Это не эффективно
@Service
public class HrenoviyService {
@Autowired
private CommonConfig config;
public JavaRDD<String> resolveOperatorNames(JavaRDD<Tuple2<String,String>> pairs){
return
pairs.filter(pair-> config.countries().contains(pair._1))
.map(pair-> config.getOperator(pair._2).getName());
}
}
Broadcast
А в чём проблема?
Нарушение инверсии контроля
ЧО?
@Service
public class HrenoviyService {
@Autowired
private JavaSparkContext sc;
@Autowired
private CommonConfig commonConfig;
private Broadcast<CommonConfig> configBroadcast;
@PostConstruct
public void wrapWithBroadCast(){
configBroadcast = sc.broadcast(commonConfig);
}
public JavaRDD<String> resolveOperatorNames(JavaRDD<Tuple2<String,String>> pairs){
return pairs.filter(pair-> configBroadcast.value().countries().contains(pair._1))
.map(pair-> configBroadcast.value().getOperator(pair._2).getName());
}
}
А в чём проблема?
Нарушение инверсии
контроля
Ну так себе нарушение,
не контекст же Спринга
инжектим
Не убедил
Много копи паста
Не так уж и много,
пара строчек
Не убедил
@Autowired
private JavaSparkContext sc;
@Autowired
private CommonConfig commonConfig;
private Broadcast<CommonConfig> configBroadcast;
@PostConstruct
public void wrapWithBroadCast(){
configBroadcast = sc.broadcast(commonConfig);
}
}
Технический спарковый код в
бизнес логике
А он у тебя всё равно где
то будет в бизнес логике
Не убедил
Но не в каждом же сервисе,
которому нужен броадкаст
…
Не убедил
Дополнительные сложности
для тестов
Они и так не 100% unit
тесты
Не убедил
Есть ещё аргумент
Убедил
Caused by: java.io.NotSerializableException: com.inwhite.HrenoviyService
Serialization stack:
- object not serializable (class: com.inwhite.HrenoviyService, value: com.inwhite.HrenoviyService@4fa4f485)
- element of array (index: 0)
- array (class [Ljava.lang.Object;, size 1)
- field (class: java.lang.invoke.SerializedLambda, name: capturedArgs, type: class [Ljava.lang.Object;)
- object (class java.lang.invoke.SerializedLambda, SerializedLambda[capturingClass=class com.inwhite.HrenoviyService,
functionalInterfaceMethod=org/apache/spark/api/java/function/Function.call:(Ljava/lang/Object;)Ljava/lang/Object;,
implementation=invokeSpecial
com/inwhite/PopularWordsResolver.lambda$mostUsedWords$29bd749d$1:(Ljava/lang/String;)Ljava/lang/Boolean;,
instantiatedMethodType=(Ljava/lang/String;)Ljava/lang/Boolean;, numCaptured=1])
- writeReplace data (class: java.lang.invoke.SerializedLambda)
- object (class com.inwhite.HrenoviyService$$Lambda$6/1775488894, com.inwhite. com.inwhite.HrenoviyService
$$Lambda$6/1775488894@5ec1963c)
- field (class: org.apache.spark.api.java.JavaRDD$$anonfun$filter$1, name: f$1, type: interface
org.apache.spark.api.java.function.Function)
- object (class org.apache.spark.api.java.JavaRDD$$anonfun$filter$1, <function1>)
at org.apache.spark.serializer.SerializationDebugger$.improveException(SerializationDebugger.scala:40)
at org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:47)
at org.apache.spark.serializer.JavaSerializerInstance.serialize(JavaSerializer.scala:101)
at org.apache.spark.util.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:301)
... 44 more
@Service
public class HrenoviyService {
@Autowired
private CommonConfig commonConfig;
public JavaRDD<String> resolveOperatorNames(JavaRDD<Tuple2<String,String>> pairs){
return pairs.filter(pair-> commonConfig.countries().contains(pair._1))
.map(pair->commonConfig.getOperator(pair._2).getName());
}
}
Ну тогда
так
//@Service
public class HrenoviyService {
// @Autowired
private Broadcast<CommonConfig> commonConfig;
public void setCommonConfig(Broadcast<CommonConfig> commonConfig) {
this.commonConfig = commonConfig;
}
public JavaRDD<String> resolveOperatorNames(JavaRDD<Tuple2<String,String>> pairs){
return pairs.filter(pair-> commonConfig.value().countries().contains(pair._1))
.map(pair->commonConfig.value().getOperator(pair._2).getName());
}
}
Ну тогда
так
@Configuration
@ComponentScan(basePackages = "ppt")
public class SpringConfig {
@Autowired
private CommonConfig commonConfig;
@Bean
public HrenoviyService hrenoviyService(){
HrenoviyService hrenoviyService = new HrenoviyService();
hrenoviyService.setCommonConfig(sc().broadcast(commonConfig));
return hrenoviyService;
}
@Bean
public JavaSparkContext sc() {
SparkConf conf = new SparkConf();
conf.setAppName("songs");
conf.setMaster("local[*]");
return new JavaSparkContext(conf);
}
}
Ну тогда
так
Иди и сделай правильно
Сравнение синтаксиса
Java
lines.map(String::toLowerCase)
.flatMap(WordsUtil::getWords)
.filter(word-> !Arrays.asList(garbage).contains(word))
.mapToPair(word-> new Tuple2<>(word, 1))
.reduceByKey((x, y)->x+y)
.mapToPair(Tuple2::swap)
.sortByKey(false)
.map(Tuple2::_2)
.take(amount);
Сравнение синтаксиса
Java Scala
lines.map(String::toLowerCase)
.flatMap(WordsUtil::getWords)
.filter(word-> !Arrays.asList(garbage).contains(word))
.mapToPair(word-> new Tuple2<>(word, 1))
.reduceByKey((x, y)->x+y)
.mapToPair(Tuple2::swap)
.sortByKey(false)
.map(Tuple2::_2)
.take(amount);
lines.map(_.toLowerCase())
.flatMap("w+".r.findAllIn(_))
.filter(!garbage.contains(_))
.map((_,1)).reduceByKey(_+_)
.sortBy(_._2,ascending = false)
.take(amount)
Говно ваша JAVA 8
Все персонажи вымышлены,
любое сходство с реальными людьми случайно!
Чем будем крыть?
Чем будем крыть?
DataFrames
Dataframes – since 1.3
• DataFrame is a distributed collection of data organized into named
columns
• Под капотом RDD, но там много оптимизаций
• Датафрэймы требуют меньше памяти, если их умно использовать
• Можно создать из hive таблиц, json подобных файлов, обычных
RDD, внешних баз данных, и из всего имеющего структуру
• Имеет очень широкий DSL
• Cвязан с SqlContext
Dataframes methods and functions
Agg, columns, count, distinct, drop, dropDuplicates, filter
groupBy, orderBy, registerTable, schema, show, select, where,
withColumn
Немного методов Датафрэймов
Agg, columns, count, distinct, drop, dropDuplicates, filter
groupBy, orderBy, registerTable, schema, show, select, where,
withColumn
dataFrame.registerTempTable("finalMap");
DataFrame frame = sqlContext.sql("select cl_id, cl_grp_id, dk_org_snw, dk_org_hnw,
dk_org_cnp, dk_dir, dk_dat, DK_TIM_HR as dk_tim_hr, dk_spe, dk_sgt, dk_pet, dk_sgs, dk_sbp,n" +
"SUM(slu_atpt) slu_atpt, SUM(slu_succ) slu_succ, SUM(slu_fail) slu_fail, SUM(slu_dly) slu_dlyn" +
"FROM finalMap f join tdtim t on f.dk_tim = t.DK_TIMn" +
"WHERE dk_pet IN (1, 4)n" +
"group by cl_id, cl_grp_id, dk_org_snw, dk_org_hnw, dk_org_cnp, dk_dir, dk_dat, DK_TIM_HR,
dk_spe, dk_sgt, dk_pet, dk_sgs, dk_sbp").toDF();
Не говорите ему про SqlContext
Почему я не люблю sql нигде
DataFrame dataFrame1 = sqlContext.sql("select tdmco.CL_ID as cl_id, n" +
"tttmdcl.CL_GRP_ID as cl_grp_id, n" +
"tttdpet.DK_PET as dk_pet, n" +
"tttdsgt.DK_SGT as dk_sgt, n" +
"tttdsgs.DK_SGS as dk_sgs, n" +
"tttddir.DK_DIR as dk_dir, n" +
"tttdorg.DK_ORG as dk_org_cnp,n" +
"ttcase when data.INBOUND_IND = 0 then tdorg.DK_ORG when data.INBOUND_IND = 1 then tdmco.CL_ID end as dk_org_hnw,n" +
"ttcase when data.INBOUND_IND = 1 then tdorg.DK_ORG when data.INBOUND_IND = 0 then tdmco.CL_ID end as dk_org_snw,n" +
"tttddat.DK_DAT as dk_dat,n" +
"tttdtim.DK_TIM as dk_tim,n" +
"ttcast(case when spe1.DK_SPE is not null then spe1.DK_SPE when spe2.DK_SPE is not null then spe2.DK_SPE when spe3.DK_SPE is not null then spe3.DK_SPE else 0 end as big
"ttcast(-999 as bigint) as dk_sgl, n" +
"ttcast(-999 as bigint) as dk_adt,n" +
"ttcast(0 as bigint) as dk_sbp,n" +
"ttdata.IMSI as dd_imsi,n" +
"ttMSISDN as dd_msisdn_min, n" +
"ttMSC as dd_msc, n" +
"ttHLR as dd_hlr, n" +
"ttSGSN_GT as dd_sgsn_gt, n" +
"ttSGSN_IP as dd_sgsn_ip,n" +
"ttcast(1 as bigint) as slu_atpt,n" +
"ttcast(case when data.STATUS = 'OK' then 1 else 0 end as bigint) as slu_succ,n" +
"ttcast(case when data.STATUS = 'Reject' then 1 else 0 end as bigint) as slu_fail,n" +
"ttcast(((unix_timestamp(substring(data.TIME_END,1,19))*1000)+(substring(data.TIME_END,21,3)))-((unix_timestamp(substring(data.TIME,1,19))*1000)+(substring(data.TIME,21
"ttdata.STATUS as statusn" +
"tt-- first_value(tmdsbsprf.PRF_ID) OVER (PARTITION BY tdmco.CL_ID,data.IMSI ORDER BY length(tmdsbsprf.MATCH_STR) desc,tmdsbsprf.MATCH_START) AS sbs_prf_if,n" +
"from data left join tdmco on (data.OWNER_CODE=tdmco.MCO_TAP_CD)n" +
"left join tmdcl on (tdmco.CL_ID=tmdcl.CL_ID)n" +
"left join tdpet on (data.OPCODE=tdpet.PET_CD)n" +
"left join tdsgt on (case when data.OPCODE = 2 then 'C' when data.OPCODE = 23 then 'P' end = tdsgt.SGT_CD)n" +
"left join tdsgs on (case when data.STATUS = 'OK' then 'S' when data.STATUS = 'Reject' then 'F' end = tdsgs.SGS_CD)n" +
"left join tddir on (case when data.INBOUND_IND = 0 then 'V' when data.INBOUND_IND = 1 then 'O' end = tddir.DIR_CD)n" +
"left join tdorg on (data.OP_ID = tdorg.ORG_TAP_CD)n" +
"left join tddat on (to_date(data.TIME) = to_date(tddat.DAT))n" +
"left join tdtim on (substring(data.TIME,12,8) = tdtim.TIM)n" +
"left join tdspe as spe1 on (case when data.STATUS = 'Reject' and data.MAP_ERR is null and TCAP_ERR is null then 255 end = spe1.SPE_CD and spe1.SPE_CAT = 'MAP')n" +
"left join tdspe as spe2 on (case when data.TCAP_ERR is null or (data.MAP_ERR is not null and data.TCAP_ERR is not null) then data.MAP_ERR end = spe2.SPE_CD and spe2.SPE_
"left join tdspe as spe3 on (case when data.MAP_ERR is null and data.TCAP_ERR is not null then data.TCAP_ERR end = spe3.SPE_CD and spe3.SPE_CAT = 'TCAP')n" +
"-- left join tmdsbsprf on (tdmco.CL_ID = tmdsbsprf.org_tech_id and SUBSTR(data.IMSI, tmdsbsprf.MATCH_START, LENGTH(tmdsbsprf.MATCH_STR)) = tmdsbsprf.MATCH_STR and to_dat
Dataframes methods and functions
• abs, cos, asin, isnull, not, rand, sqrt, when, expr, bin, atan, ceil, floor,
factorial, greatest, least, log, log10, pow, round, sin, toDegrees,
toRadians, md5, ascii, base64, concat, length, lower, ltrim, unbase64,
repeat, reverse, split, substring, trim, upper, datediff, year, month,
hour, last_day, next_day, dayofmonth, explode, udf
Dataframes methods and functions
• abs, cos, asin, isnull, not, rand, sqrt, when, expr, bin, atan, ceil, floor,
factorial, greatest, least, log, log10, pow, round, sin, toDegrees,
toRadians, md5, ascii, base64, concat, length, lower, ltrim, unbase64,
repeat, reverse, split, substring, trim, upper, datediff, year, month,
hour, last_day, next_day, dayofmonth, explode, udf
Пример Датафрэйма
Миф четвёртый
• Датафрэймы можно использовать только для файлов со схемой
Функций много, но если надо свою?
@Component
public class GarbageFilter implements UDF1<String,Boolean> {
@Value("${garbage}")
private String[] garbage;
public String udfName(){return "notGarbage";}
@Override
public Boolean call(String word) throws Exception {
return !Arrays.asList(garbage).contains(word);
}
}
Как пользоваться UDF функциями?
@Service
public class PopularWordsResolverWithUDF {
@Autowired
private GarbageFilter garbageFilter;
@Autowired
private SQLContext sqlContext;
@PostConstruct
public void registerUdf(){
sqlContext.udf().register(garbageFilter.udfName(),garbageFilter, DataTypes.BooleanType);
}
public List<String> mostUsedWords(DataFrame dataFrame, int amount) {
DataFrame sorted = dataFrame.withColumn("words", lower(column("words")))
.filter(callUDF(garbageFilter.udfName(),column("words")))…
Итоги и выводы
• Hadoop нуждается в Спарке, а не наоборот
• Можно отлично обойтись без Скалы
• Можно использовать привычный вам подход:
• Инверсия контроля, Spring, Шаблоны проектирования
• Можно прекрасно писать тесты
• Можно везде (ну почти) пользоваться Датафрэймами
• И главное:
Pink Floyd не попса!!!
Спасибо Баруху и Егору за предоставленные фото
Спасибо моей дочке за предоставленные тексты песен
Все остальные персонажи вымышлены,
любое сходство с реальными людьми случайно!

Weitere ähnliche Inhalte

Was ist angesagt?

Jbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot StarterJbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot StarterAleksandr Tarasov
 
Golang в действии: Как нам удается писать highload приложение на (не?)подходя...
Golang в действии: Как нам удается писать highload приложение на (не?)подходя...Golang в действии: Как нам удается писать highload приложение на (не?)подходя...
Golang в действии: Как нам удается писать highload приложение на (не?)подходя...Daniel Podolsky
 
Database First! О распространённых ошибках использования РСУБД
Database First! О распространённых ошибках использования РСУБДDatabase First! О распространённых ошибках использования РСУБД
Database First! О распространённых ошибках использования РСУБДNikolay Samokhvalov
 
Расширь границы возможного вместе с Gradle
Расширь границы возможного вместе с GradleРасширь границы возможного вместе с Gradle
Расширь границы возможного вместе с GradleAleksandr Tarasov
 
Server Side Javascript (ru)
Server Side Javascript (ru)Server Side Javascript (ru)
Server Side Javascript (ru)Bakyt Niyazov
 
Micro-services, Упрощаем монолитные приложения
Micro-services, Упрощаем монолитные приложенияMicro-services, Упрощаем монолитные приложения
Micro-services, Упрощаем монолитные приложенияRinat Abdullin
 
NoSQL — неспроста ли это "ЖЖЖ"?
NoSQL — неспроста ли это "ЖЖЖ"?NoSQL — неспроста ли это "ЖЖЖ"?
NoSQL — неспроста ли это "ЖЖЖ"?Daniel Podolsky
 
"Портирование Web SDK с JS на TS" Петров Григорий, Voximplant
"Портирование Web SDK с JS на TS" Петров Григорий, Voximplant"Портирование Web SDK с JS на TS" Петров Григорий, Voximplant
"Портирование Web SDK с JS на TS" Петров Григорий, Voximplantit-people
 
Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)Fedor Malyshkin
 
My talk at YouCon Saratov 2016
My talk at YouCon Saratov 2016My talk at YouCon Saratov 2016
My talk at YouCon Saratov 2016Alex Chistyakov
 
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...Fwdays
 
Всему своё время / Роман Ивлиев (Банки.ру)
Всему своё время / Роман Ивлиев (Банки.ру)Всему своё время / Роман Ивлиев (Банки.ру)
Всему своё время / Роман Ивлиев (Банки.ру)Ontico
 
Инструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныИнструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныRoman Dvornov
 
Григорий Петров "WebRTC в мобильных приложениях при помощи React Native"
Григорий Петров "WebRTC в мобильных приложениях при помощи React Native"Григорий Петров "WebRTC в мобильных приложениях при помощи React Native"
Григорий Петров "WebRTC в мобильных приложениях при помощи React Native"IT Event
 
неприятная правда про язык go
неприятная правда про язык goнеприятная правда про язык go
неприятная правда про язык goDaniel Podolsky
 
How to cook a blockchain and not get burned
How to cook a blockchain and not get burned How to cook a blockchain and not get burned
How to cook a blockchain and not get burned Alexander Syrotenko
 
My talk on HBase ops engineering at TBD Jun 2016
My talk on HBase ops engineering at TBD Jun 2016My talk on HBase ops engineering at TBD Jun 2016
My talk on HBase ops engineering at TBD Jun 2016Alex Chistyakov
 

Was ist angesagt? (20)

Jbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot StarterJbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot Starter
 
Remote Highload
Remote HighloadRemote Highload
Remote Highload
 
Golang в действии: Как нам удается писать highload приложение на (не?)подходя...
Golang в действии: Как нам удается писать highload приложение на (не?)подходя...Golang в действии: Как нам удается писать highload приложение на (не?)подходя...
Golang в действии: Как нам удается писать highload приложение на (не?)подходя...
 
Database First! О распространённых ошибках использования РСУБД
Database First! О распространённых ошибках использования РСУБДDatabase First! О распространённых ошибках использования РСУБД
Database First! О распространённых ошибках использования РСУБД
 
Расширь границы возможного вместе с Gradle
Расширь границы возможного вместе с GradleРасширь границы возможного вместе с Gradle
Расширь границы возможного вместе с Gradle
 
Server Side Javascript (ru)
Server Side Javascript (ru)Server Side Javascript (ru)
Server Side Javascript (ru)
 
Micro-services, Упрощаем монолитные приложения
Micro-services, Упрощаем монолитные приложенияMicro-services, Упрощаем монолитные приложения
Micro-services, Упрощаем монолитные приложения
 
NoSQL — неспроста ли это "ЖЖЖ"?
NoSQL — неспроста ли это "ЖЖЖ"?NoSQL — неспроста ли это "ЖЖЖ"?
NoSQL — неспроста ли это "ЖЖЖ"?
 
"Портирование Web SDK с JS на TS" Петров Григорий, Voximplant
"Портирование Web SDK с JS на TS" Петров Григорий, Voximplant"Портирование Web SDK с JS на TS" Петров Григорий, Voximplant
"Портирование Web SDK с JS на TS" Петров Григорий, Voximplant
 
Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)
 
My talk at YouCon Saratov 2016
My talk at YouCon Saratov 2016My talk at YouCon Saratov 2016
My talk at YouCon Saratov 2016
 
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
 
Всему своё время / Роман Ивлиев (Банки.ру)
Всему своё время / Роман Ивлиев (Банки.ру)Всему своё время / Роман Ивлиев (Банки.ру)
Всему своё время / Роман Ивлиев (Банки.ру)
 
Инструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныИнструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важны
 
Григорий Петров "WebRTC в мобильных приложениях при помощи React Native"
Григорий Петров "WebRTC в мобильных приложениях при помощи React Native"Григорий Петров "WebRTC в мобильных приложениях при помощи React Native"
Григорий Петров "WebRTC в мобильных приложениях при помощи React Native"
 
неприятная правда про язык go
неприятная правда про язык goнеприятная правда про язык go
неприятная правда про язык go
 
How to cook a blockchain and not get burned
How to cook a blockchain and not get burned How to cook a blockchain and not get burned
How to cook a blockchain and not get burned
 
Chef @DevWeb
Chef @DevWebChef @DevWeb
Chef @DevWeb
 
My talk on HBase ops engineering at TBD Jun 2016
My talk on HBase ops engineering at TBD Jun 2016My talk on HBase ops engineering at TBD Jun 2016
My talk on HBase ops engineering at TBD Jun 2016
 
За пределами PageObject
За пределами PageObjectЗа пределами PageObject
За пределами PageObject
 

Andere mochten auch

Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)Alexey Fyodorov
 
Spring Framework Essentials
Spring Framework EssentialsSpring Framework Essentials
Spring Framework EssentialsEdward Goikhman
 
JEE Conf: Архитектура Android приложений: полезные и вредные советы
JEE Conf: Архитектура Android приложений: полезные и вредные советыJEE Conf: Архитектура Android приложений: полезные и вредные советы
JEE Conf: Архитектура Android приложений: полезные и вредные советыdmalykhanov
 
JDK: CPU, PSU, LU, FR — WTF?!
JDK: CPU, PSU, LU, FR — WTF?!JDK: CPU, PSU, LU, FR — WTF?!
JDK: CPU, PSU, LU, FR — WTF?!Alexey Fyodorov
 
Pragmatic functional refactoring with java 8 (1)
Pragmatic functional refactoring with java 8 (1)Pragmatic functional refactoring with java 8 (1)
Pragmatic functional refactoring with java 8 (1)RichardWarburton
 
Hot and spicy Java with Lombok. Live!
Hot and spicy Java with Lombok. Live!Hot and spicy Java with Lombok. Live!
Hot and spicy Java with Lombok. Live!Vladimir Tsukur
 
Java EE 7: Developing for the Cloud at Geecon, JEEConf, Johannesburg
Java EE 7: Developing for the Cloud at Geecon, JEEConf, JohannesburgJava EE 7: Developing for the Cloud at Geecon, JEEConf, Johannesburg
Java EE 7: Developing for the Cloud at Geecon, JEEConf, JohannesburgArun Gupta
 
What Mr. Spock would possibly say about modern unit testing: pragmatic and em...
What Mr. Spock would possibly say about modern unit testing: pragmatic and em...What Mr. Spock would possibly say about modern unit testing: pragmatic and em...
What Mr. Spock would possibly say about modern unit testing: pragmatic and em...Yaroslav Yermilov
 
Java garbage collection & GC friendly coding
Java garbage collection  & GC friendly codingJava garbage collection  & GC friendly coding
Java garbage collection & GC friendly codingMd Ayub Ali Sarker
 
Search and analyze your data with elasticsearch
Search and analyze your data with elasticsearchSearch and analyze your data with elasticsearch
Search and analyze your data with elasticsearchAnton Udovychenko
 
Scalable Java Application Development on AWS
Scalable Java Application Development on AWSScalable Java Application Development on AWS
Scalable Java Application Development on AWSMikalai Alimenkou
 
Let's Learn to Talk to GC Logs in Java 9
Let's Learn to Talk to GC Logs in Java 9Let's Learn to Talk to GC Logs in Java 9
Let's Learn to Talk to GC Logs in Java 9Poonam Bajaj Parhar
 
How Immutability Helps in OOP
How Immutability Helps in OOPHow Immutability Helps in OOP
How Immutability Helps in OOPYegor Bugayenko
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring FrameworkDineesha Suraweera
 
Reactive Thinking in Java
Reactive Thinking in JavaReactive Thinking in Java
Reactive Thinking in JavaYakov Fain
 

Andere mochten auch (20)

Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)
 
Spring Framework Essentials
Spring Framework EssentialsSpring Framework Essentials
Spring Framework Essentials
 
JEE Conf: Архитектура Android приложений: полезные и вредные советы
JEE Conf: Архитектура Android приложений: полезные и вредные советыJEE Conf: Архитектура Android приложений: полезные и вредные советы
JEE Conf: Архитектура Android приложений: полезные и вредные советы
 
Spock
SpockSpock
Spock
 
JDK: CPU, PSU, LU, FR — WTF?!
JDK: CPU, PSU, LU, FR — WTF?!JDK: CPU, PSU, LU, FR — WTF?!
JDK: CPU, PSU, LU, FR — WTF?!
 
Java 8 puzzlers
Java 8 puzzlersJava 8 puzzlers
Java 8 puzzlers
 
Pragmatic functional refactoring with java 8 (1)
Pragmatic functional refactoring with java 8 (1)Pragmatic functional refactoring with java 8 (1)
Pragmatic functional refactoring with java 8 (1)
 
Hot and spicy Java with Lombok. Live!
Hot and spicy Java with Lombok. Live!Hot and spicy Java with Lombok. Live!
Hot and spicy Java with Lombok. Live!
 
Java EE 7: Developing for the Cloud at Geecon, JEEConf, Johannesburg
Java EE 7: Developing for the Cloud at Geecon, JEEConf, JohannesburgJava EE 7: Developing for the Cloud at Geecon, JEEConf, Johannesburg
Java EE 7: Developing for the Cloud at Geecon, JEEConf, Johannesburg
 
What Mr. Spock would possibly say about modern unit testing: pragmatic and em...
What Mr. Spock would possibly say about modern unit testing: pragmatic and em...What Mr. Spock would possibly say about modern unit testing: pragmatic and em...
What Mr. Spock would possibly say about modern unit testing: pragmatic and em...
 
Java garbage collection & GC friendly coding
Java garbage collection  & GC friendly codingJava garbage collection  & GC friendly coding
Java garbage collection & GC friendly coding
 
Search and analyze your data with elasticsearch
Search and analyze your data with elasticsearchSearch and analyze your data with elasticsearch
Search and analyze your data with elasticsearch
 
Scalable Java Application Development on AWS
Scalable Java Application Development on AWSScalable Java Application Development on AWS
Scalable Java Application Development on AWS
 
Let's Learn to Talk to GC Logs in Java 9
Let's Learn to Talk to GC Logs in Java 9Let's Learn to Talk to GC Logs in Java 9
Let's Learn to Talk to GC Logs in Java 9
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
How Immutability Helps in OOP
How Immutability Helps in OOPHow Immutability Helps in OOP
How Immutability Helps in OOP
 
Spring
SpringSpring
Spring
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework
 
Spring Framework
Spring FrameworkSpring Framework
Spring Framework
 
Reactive Thinking in Java
Reactive Thinking in JavaReactive Thinking in Java
Reactive Thinking in Java
 

Ähnlich wie мифы о спарке

Минуты из жизни со Spark
Минуты из жизни со SparkМинуты из жизни со Spark
Минуты из жизни со SparkRamblerML
 
Spark overview (18.06.2015)
Spark overview (18.06.2015)Spark overview (18.06.2015)
Spark overview (18.06.2015)bddmoscow
 
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)Ontico
 
Пайплайн машинного обучения на Apache Spark
Пайплайн машинного обучения на Apache SparkПайплайн машинного обучения на Apache Spark
Пайплайн машинного обучения на Apache SparkRamblerML
 
Егор Матешук. МаксимаТелеком. Не Spark’ом единым — полезные инструменты для с...
Егор Матешук. МаксимаТелеком. Не Spark’ом единым — полезные инструменты для с...Егор Матешук. МаксимаТелеком. Не Spark’ом единым — полезные инструменты для с...
Егор Матешук. МаксимаТелеком. Не Spark’ом единым — полезные инструменты для с...Global Innovation Labs
 
Сергей Житинский, Александр Чистяков (Git in Sky)
Сергей Житинский, Александр Чистяков (Git in Sky)Сергей Житинский, Александр Чистяков (Git in Sky)
Сергей Житинский, Александр Чистяков (Git in Sky)Ontico
 
Expert Fridays Spark Job
Expert Fridays Spark JobExpert Fridays Spark Job
Expert Fridays Spark JobProvectus
 
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...Ruby Meditation
 
Platypus platform ivbit
Platypus platform ivbitPlatypus platform ivbit
Platypus platform ivbitjskonst
 
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?RAMBLER&Co
 
[Expert Fridays] Python MeetUp - Леонид Блохин: "Нейросети на питоне: пфф easy"
[Expert Fridays] Python MeetUp - Леонид Блохин: "Нейросети на питоне: пфф  easy"[Expert Fridays] Python MeetUp - Леонид Блохин: "Нейросети на питоне: пфф  easy"
[Expert Fridays] Python MeetUp - Леонид Блохин: "Нейросети на питоне: пфф easy"Provectus
 
Архитектура Apache Spark
Архитектура Apache SparkАрхитектура Apache Spark
Архитектура Apache SparkRamblerML
 
С.Лалов "Corona SDK для разработки кроссплатформенных приложений", DUMP-2014
С.Лалов "Corona SDK для разработки кроссплатформенных приложений", DUMP-2014С.Лалов "Corona SDK для разработки кроссплатформенных приложений", DUMP-2014
С.Лалов "Corona SDK для разработки кроссплатформенных приложений", DUMP-2014it-people
 
Машинное обучение в электронной коммерции - практика использования и подводны...
Машинное обучение в электронной коммерции - практика использования и подводны...Машинное обучение в электронной коммерции - практика использования и подводны...
Машинное обучение в электронной коммерции - практика использования и подводны...Ontico
 
SmartOS/Solaris app tuning tools/technologies on HL++ 2013
SmartOS/Solaris app tuning tools/technologies on HL++ 2013SmartOS/Solaris app tuning tools/technologies on HL++ 2013
SmartOS/Solaris app tuning tools/technologies on HL++ 2013Alex Chistyakov
 
Git in Sky presentation @ HighLoad++ 2013
Git in Sky presentation @ HighLoad++ 2013Git in Sky presentation @ HighLoad++ 2013
Git in Sky presentation @ HighLoad++ 2013Serguei Gitinsky
 
Сравнение ТОП 5 SIEM РФ
Сравнение ТОП 5 SIEM РФСравнение ТОП 5 SIEM РФ
Сравнение ТОП 5 SIEM РФPete Kuzeev
 
Скажи мне правду, Scrum, когда тестировать нам?
Скажи мне правду, Scrum, когда тестировать нам?Скажи мне правду, Scrum, когда тестировать нам?
Скажи мне правду, Scrum, когда тестировать нам?SQALab
 
Perl, и с чем его едят. Доклад нашего Главного Инженера (ГИ) Александра Чистя...
Perl, и с чем его едят. Доклад нашего Главного Инженера (ГИ) Александра Чистя...Perl, и с чем его едят. Доклад нашего Главного Инженера (ГИ) Александра Чистя...
Perl, и с чем его едят. Доклад нашего Главного Инженера (ГИ) Александра Чистя...Serguei Gitinsky
 
Мой modern Perl (весенняя встреча Piter United)
Мой modern Perl (весенняя встреча Piter United)Мой modern Perl (весенняя встреча Piter United)
Мой modern Perl (весенняя встреча Piter United)Alex Chistyakov
 

Ähnlich wie мифы о спарке (20)

Минуты из жизни со Spark
Минуты из жизни со SparkМинуты из жизни со Spark
Минуты из жизни со Spark
 
Spark overview (18.06.2015)
Spark overview (18.06.2015)Spark overview (18.06.2015)
Spark overview (18.06.2015)
 
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
 
Пайплайн машинного обучения на Apache Spark
Пайплайн машинного обучения на Apache SparkПайплайн машинного обучения на Apache Spark
Пайплайн машинного обучения на Apache Spark
 
Егор Матешук. МаксимаТелеком. Не Spark’ом единым — полезные инструменты для с...
Егор Матешук. МаксимаТелеком. Не Spark’ом единым — полезные инструменты для с...Егор Матешук. МаксимаТелеком. Не Spark’ом единым — полезные инструменты для с...
Егор Матешук. МаксимаТелеком. Не Spark’ом единым — полезные инструменты для с...
 
Сергей Житинский, Александр Чистяков (Git in Sky)
Сергей Житинский, Александр Чистяков (Git in Sky)Сергей Житинский, Александр Чистяков (Git in Sky)
Сергей Житинский, Александр Чистяков (Git in Sky)
 
Expert Fridays Spark Job
Expert Fridays Spark JobExpert Fridays Spark Job
Expert Fridays Spark Job
 
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
Reinventing the wheel - why do it and how to feel good about it - Julik Tarkh...
 
Platypus platform ivbit
Platypus platform ivbitPlatypus platform ivbit
Platypus platform ivbit
 
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?
 
[Expert Fridays] Python MeetUp - Леонид Блохин: "Нейросети на питоне: пфф easy"
[Expert Fridays] Python MeetUp - Леонид Блохин: "Нейросети на питоне: пфф  easy"[Expert Fridays] Python MeetUp - Леонид Блохин: "Нейросети на питоне: пфф  easy"
[Expert Fridays] Python MeetUp - Леонид Блохин: "Нейросети на питоне: пфф easy"
 
Архитектура Apache Spark
Архитектура Apache SparkАрхитектура Apache Spark
Архитектура Apache Spark
 
С.Лалов "Corona SDK для разработки кроссплатформенных приложений", DUMP-2014
С.Лалов "Corona SDK для разработки кроссплатформенных приложений", DUMP-2014С.Лалов "Corona SDK для разработки кроссплатформенных приложений", DUMP-2014
С.Лалов "Corona SDK для разработки кроссплатформенных приложений", DUMP-2014
 
Машинное обучение в электронной коммерции - практика использования и подводны...
Машинное обучение в электронной коммерции - практика использования и подводны...Машинное обучение в электронной коммерции - практика использования и подводны...
Машинное обучение в электронной коммерции - практика использования и подводны...
 
SmartOS/Solaris app tuning tools/technologies on HL++ 2013
SmartOS/Solaris app tuning tools/technologies on HL++ 2013SmartOS/Solaris app tuning tools/technologies on HL++ 2013
SmartOS/Solaris app tuning tools/technologies on HL++ 2013
 
Git in Sky presentation @ HighLoad++ 2013
Git in Sky presentation @ HighLoad++ 2013Git in Sky presentation @ HighLoad++ 2013
Git in Sky presentation @ HighLoad++ 2013
 
Сравнение ТОП 5 SIEM РФ
Сравнение ТОП 5 SIEM РФСравнение ТОП 5 SIEM РФ
Сравнение ТОП 5 SIEM РФ
 
Скажи мне правду, Scrum, когда тестировать нам?
Скажи мне правду, Scrum, когда тестировать нам?Скажи мне правду, Scrum, когда тестировать нам?
Скажи мне правду, Scrum, когда тестировать нам?
 
Perl, и с чем его едят. Доклад нашего Главного Инженера (ГИ) Александра Чистя...
Perl, и с чем его едят. Доклад нашего Главного Инженера (ГИ) Александра Чистя...Perl, и с чем его едят. Доклад нашего Главного Инженера (ГИ) Александра Чистя...
Perl, и с чем его едят. Доклад нашего Главного Инженера (ГИ) Александра Чистя...
 
Мой modern Perl (весенняя встреча Piter United)
Мой modern Perl (весенняя встреча Piter United)Мой modern Perl (весенняя встреча Piter United)
Мой modern Perl (весенняя встреча Piter United)
 

Mehr von Evgeny Borisov

Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2Evgeny Borisov
 
Groovy jug-moscow-part 1
Groovy jug-moscow-part 1Groovy jug-moscow-part 1
Groovy jug-moscow-part 1Evgeny Borisov
 
Javaone 2013 moscow gradle english
Javaone 2013 moscow gradle   englishJavaone 2013 moscow gradle   english
Javaone 2013 moscow gradle englishEvgeny Borisov
 

Mehr von Evgeny Borisov (6)

Spring puzzlers 2
Spring puzzlers 2Spring puzzlers 2
Spring puzzlers 2
 
Spring puzzlers
Spring puzzlersSpring puzzlers
Spring puzzlers
 
Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2
 
Groovy jug-moscow-part 1
Groovy jug-moscow-part 1Groovy jug-moscow-part 1
Groovy jug-moscow-part 1
 
Spring the ripper
Spring the ripperSpring the ripper
Spring the ripper
 
Javaone 2013 moscow gradle english
Javaone 2013 moscow gradle   englishJavaone 2013 moscow gradle   english
Javaone 2013 moscow gradle english
 

мифы о спарке

  • 2. О себе • Пишу на джаве с 2001 • Преподаю джаву с 2003 • Консультирую с 2008 • Арихтектор с 2009 • Пилю стартап с 2014 • Техлид по биг дате с 2015 • Naya technologies c 2015
  • 3. Опровержение мифов • Концептуальные мифы • Spark это какая то хрень для Hadoop-a • Spark надо писать на скале • Spark и Spring не совместимы, и вообще там всё по другому • Для Spark-а нельзя сложно писать unit тесты • Технические мифы • Broadcast – это не только для перформэнса • Датафрэймы можно использовать только для файлов со схемой • Главный миф
  • 5. Pink Floyd это вам не Бритни Спирс или Кэтти Пери
  • 6. Миф первый о Spark-e и Hadoop-e
  • 7. Что вообще мы знаем про Hadoop
  • 9. Да да, это тот же человек
  • 10. И при чём тут Hadoop?
  • 11. Spark • Развитие • Идея зародилась в UC Berkeley примерно в 2009 • Первый релиз в 2012 • Сегодня 1.6 с января 2016 • Spark 2.0 – скоро • Написан на скале • Есть API для • Scala, Python, Java, Java 8, R • Где писать • InteliJ, Eclipse, Spark-shell, Notebooks • Запускать • Spark-Shell, Notebooks, Spark-submit • Как обычную Джаву • Что нужно чтобы можно было запускать на кластере • Какой-нибудь cluster manager
  • 13. Spark with yarn Очень важно! Часть кода исполняется на кластере Часть исполняется на драйвере
  • 15. Как можно получить RDD? • Из файла (файлов в директории) • Из памяти (обычно используется для тестов) • Из другого RDD (ну да да, как Стримы)
  • 16. // from local file system JavaRDD<String> rdd = sc.textFile("file:/home/data/data.txt"); // from Hadoop using relative path of user, who run spark application rdd = sc.textFile("/data/data.txt") // from hadoop rdd = sc.textFile("hdfs://data/data.txt") // all files from directory rdd = sc.textFile("s3://data/*") // all txt files from directory rdd = sc.textFile("s3://data/*.txt") Из файла / директории
  • 18. А что это за sc? • SparkContext / JavaSparkContext • Main entry point for Spark functionality SparkConf conf = new SparkConf(); conf.setAppName("my spark application"); conf.setMaster("local[*]"); JavaSparkContext sc = new JavaSparkContext(conf);
  • 19. Spark Context локально и продакшн @Bean @Profile("LOCAL") public JavaSparkContext sc() { SparkConf conf = new SparkConf(); conf.setAppName("music analyst"); conf.setMaster("local[1]"); return new JavaSparkContext(conf); } @Bean @Profile("PROD") public JavaSparkContext sc() { SparkConf conf = new SparkConf(); conf.setAppName("music analyst"); return new JavaSparkContext(conf); }
  • 20. Transformations • map • flatMap • filter • mapPartitions, mapPartitionsWithIndex • sample • union, intersection, join, cogroup, cartesian (otherDataset) • distinct • reduceByKey, aggregateByKey, sortByKey • pipe • coalesce, repartition, repartitionAndSortWithinPartitions
  • 21. Actions • reduce • collect • count, countByKey, countByValue • first • take, takeSample, takeOrdered • saveAsTextFile, saveAsSequenceFile, saveAsObjectFile • foreach
  • 22. Rdd flow RDD1Data transformation transformationRDD2 actionRDD3 Benefit Выполняется на кластере Да да, это всё Lazy как в стримах
  • 23. Benefit RDD1Data RDD2 RDD3 RDD4 RDD5 Benefit RDD6 Performance trouble 10 минут 10 + 1 + 1 = 12 ?
  • 24. Benefit RDD1Data RDD2 RDD3 RDD4 RDD5 Benefit RDD6 Performance trouble 10 минут 10 + 1 + 1 = 22 ! (10 х 2)
  • 25. Benefit RDD1Data RDD2 RDD3 RDD4 RDD5 Benefit RDD6 collect Что бы мы сделали в стримах? Вытащить в коллекцию, а потом создавать стрим из неё
  • 27. Benefit RDD1Data RDD2 RDD3 RDD4 RDD5 Benefit RDD6 persist Что умеет Spark
  • 28. На чём будем писать? • Scala • Java • Python • R
  • 29. Что думает о Скале обычный Java developer
  • 30. продвинутый Что думает о Скале обычный Java developer
  • 31. val lines = sc.textFile("data.txt") val lineLengths = lines.map(_.length) val totalLength = lineLengths.reduce(_+_) JavaRDD<String> lines = sc.textFile("data.txt"); JavaRDD<Integer> lineLengths = lines.map(new Function<String, Integer>() { @Override public Integer call(String lines) throws Exception { return lines.length(); } }); Integer totalLength = lineLengths.reduce(new Function2<Integer, Integer, Integer>() { @Override public Integer call(Integer a, Integer b) throws Exception { return a + b; } }); Scala Java
  • 32. Говно ваша JAVA Все персонажи вымышлены, любое сходство с реальными людьми случайно!
  • 33. val lines = sc.textFile("data.txt") val lineLengths = lines.map(_.length) val totalLength = lineLengths.reduce(_+_) Scala Java 8JavaRDD<String> lines = sc.textFile("data.txt"); JavaRDD<Integer> lineLengths = lines.map(String::length); int totalLength = lineLengths.reduce((a, b) -> a + b);
  • 34. Миф второй – Spark надо писать на Скале За Скалу За Джаву Скала это круто
  • 35. Миф второй – Spark надо писать на Скале За Скалу За Джаву Скала это круто Большинство джава программистов знает джаву
  • 36. Миф второй – Spark надо писать на Скале За Скалу За Джаву Скала это круто Большинство джава программистов знает джаву Более лаконичный и удобный синтаксис
  • 37. Миф второй – Spark надо писать на Скале За Скалу За Джаву Скала это круто Большинство джава программистов знает джаву Более лаконичный и удобный синтаксис Знакомый нам мир (Spring, шаблоны проектирования)
  • 38. Миф второй – Spark надо писать на Скале За Скалу За Джаву Скала это круто Большинство джава программистов знает джаву Более лаконичный и удобный синтаксис Знакомый нам мир (Spring, шаблоны проектирования) Spark API заточен под Скалу в первую очередь
  • 39. Миф второй – Spark надо писать на Скале За Скалу За Джаву Скала это круто Большинство джава программистов знает джаву Более лаконичный и удобный синтаксис Знакомый нам мир (Spring, шаблоны проектирования) Spark API заточен под Скалу в первую очередь
  • 40. Миф второй – Spark надо писать на Скале За Скалу За Джаву Скала это круто Большинство джава программистов знает джаву Более лаконичный и удобный синтаксис Знакомый нам мир (Spring, шаблоны проектирования) Spark API заточен под Скалу в первую очередь Java API выходит чуть позже, и не всегда всё есть
  • 41. Миф второй – Spark надо писать на Скале За Скалу За Джаву Скала это круто Большинство джава программистов знает джаву Более лаконичный и удобный синтаксис Знакомый нам мир (Spring, шаблоны проектирования) Spark API заточен под Скалу в первую очередь Большинство джава программистов знает джаву Java API выходит чуть позже, и не всегда всё есть Знакомый нам мир (Spring, шаблоны проектирования)
  • 43. Миф третий • Spark и Spring не совместимы, и вообще там всё по другому
  • 45. Shared data • Или миф следующий – есть такие случаи когда без broadcasta не будет работать
  • 46. Пример Israel, +9725423632 Israel, +9725454232 Israel, +9721454232 Israel, +9721454232 Spain, +34441323432 Spain, +34441323432 Israel, +9725423232 Israel, +9725423232 Spain, +34441323432 Russia, +78123343434 Russia, +78123343434
  • 47. Пример Israel, +9725423632 Israel, +9725454232 Israel, +9721454232 Israel, +9721454232 Spain, +34441323432 Spain, +34441323432 Israel, +9725423232 Israel, +9725423232 Spain, +34441323432 Russia, +78123343434 Russia, +78123343434
  • 48. Пример Israel, Orange Israel, Orange Israel, Pelephone Israel, Pelephone Israel, Hot Mobile Israel, Orange Russia, Megaphone Russia, MTC
  • 50. Пример Israel, +9725423632 Israel, +9725454232 Israel, +9721454232 Israel, +9721454232 Spain, +34441323432 Spain, +34441323432 Israel, +9725423232 Israel, +9725423232 Spain, +34441323432 Russia, +78123343434 Russia, +78123343434 public interface CommonConfig { Operator getOperator(String phone); List<String> countries(); }
  • 51. Это не эффективно @Service public class HrenoviyService { @Autowired private CommonConfig config; public JavaRDD<String> resolveOperatorNames(JavaRDD<Tuple2<String,String>> pairs){ return pairs.filter(pair-> config.countries().contains(pair._1)) .map(pair-> config.getOperator(pair._2).getName()); } }
  • 53. А в чём проблема? Нарушение инверсии контроля ЧО?
  • 54. @Service public class HrenoviyService { @Autowired private JavaSparkContext sc; @Autowired private CommonConfig commonConfig; private Broadcast<CommonConfig> configBroadcast; @PostConstruct public void wrapWithBroadCast(){ configBroadcast = sc.broadcast(commonConfig); } public JavaRDD<String> resolveOperatorNames(JavaRDD<Tuple2<String,String>> pairs){ return pairs.filter(pair-> configBroadcast.value().countries().contains(pair._1)) .map(pair-> configBroadcast.value().getOperator(pair._2).getName()); } } А в чём проблема?
  • 56. Ну так себе нарушение, не контекст же Спринга инжектим Не убедил
  • 58. Не так уж и много, пара строчек Не убедил @Autowired private JavaSparkContext sc; @Autowired private CommonConfig commonConfig; private Broadcast<CommonConfig> configBroadcast; @PostConstruct public void wrapWithBroadCast(){ configBroadcast = sc.broadcast(commonConfig); } }
  • 59. Технический спарковый код в бизнес логике
  • 60. А он у тебя всё равно где то будет в бизнес логике Не убедил
  • 61. Но не в каждом же сервисе, которому нужен броадкаст
  • 64. Они и так не 100% unit тесты Не убедил
  • 67. Caused by: java.io.NotSerializableException: com.inwhite.HrenoviyService Serialization stack: - object not serializable (class: com.inwhite.HrenoviyService, value: com.inwhite.HrenoviyService@4fa4f485) - element of array (index: 0) - array (class [Ljava.lang.Object;, size 1) - field (class: java.lang.invoke.SerializedLambda, name: capturedArgs, type: class [Ljava.lang.Object;) - object (class java.lang.invoke.SerializedLambda, SerializedLambda[capturingClass=class com.inwhite.HrenoviyService, functionalInterfaceMethod=org/apache/spark/api/java/function/Function.call:(Ljava/lang/Object;)Ljava/lang/Object;, implementation=invokeSpecial com/inwhite/PopularWordsResolver.lambda$mostUsedWords$29bd749d$1:(Ljava/lang/String;)Ljava/lang/Boolean;, instantiatedMethodType=(Ljava/lang/String;)Ljava/lang/Boolean;, numCaptured=1]) - writeReplace data (class: java.lang.invoke.SerializedLambda) - object (class com.inwhite.HrenoviyService$$Lambda$6/1775488894, com.inwhite. com.inwhite.HrenoviyService $$Lambda$6/1775488894@5ec1963c) - field (class: org.apache.spark.api.java.JavaRDD$$anonfun$filter$1, name: f$1, type: interface org.apache.spark.api.java.function.Function) - object (class org.apache.spark.api.java.JavaRDD$$anonfun$filter$1, <function1>) at org.apache.spark.serializer.SerializationDebugger$.improveException(SerializationDebugger.scala:40) at org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:47) at org.apache.spark.serializer.JavaSerializerInstance.serialize(JavaSerializer.scala:101) at org.apache.spark.util.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:301) ... 44 more
  • 68. @Service public class HrenoviyService { @Autowired private CommonConfig commonConfig; public JavaRDD<String> resolveOperatorNames(JavaRDD<Tuple2<String,String>> pairs){ return pairs.filter(pair-> commonConfig.countries().contains(pair._1)) .map(pair->commonConfig.getOperator(pair._2).getName()); } } Ну тогда так
  • 69. //@Service public class HrenoviyService { // @Autowired private Broadcast<CommonConfig> commonConfig; public void setCommonConfig(Broadcast<CommonConfig> commonConfig) { this.commonConfig = commonConfig; } public JavaRDD<String> resolveOperatorNames(JavaRDD<Tuple2<String,String>> pairs){ return pairs.filter(pair-> commonConfig.value().countries().contains(pair._1)) .map(pair->commonConfig.value().getOperator(pair._2).getName()); } } Ну тогда так
  • 70. @Configuration @ComponentScan(basePackages = "ppt") public class SpringConfig { @Autowired private CommonConfig commonConfig; @Bean public HrenoviyService hrenoviyService(){ HrenoviyService hrenoviyService = new HrenoviyService(); hrenoviyService.setCommonConfig(sc().broadcast(commonConfig)); return hrenoviyService; } @Bean public JavaSparkContext sc() { SparkConf conf = new SparkConf(); conf.setAppName("songs"); conf.setMaster("local[*]"); return new JavaSparkContext(conf); } } Ну тогда так
  • 71. Иди и сделай правильно
  • 72. Сравнение синтаксиса Java lines.map(String::toLowerCase) .flatMap(WordsUtil::getWords) .filter(word-> !Arrays.asList(garbage).contains(word)) .mapToPair(word-> new Tuple2<>(word, 1)) .reduceByKey((x, y)->x+y) .mapToPair(Tuple2::swap) .sortByKey(false) .map(Tuple2::_2) .take(amount);
  • 73. Сравнение синтаксиса Java Scala lines.map(String::toLowerCase) .flatMap(WordsUtil::getWords) .filter(word-> !Arrays.asList(garbage).contains(word)) .mapToPair(word-> new Tuple2<>(word, 1)) .reduceByKey((x, y)->x+y) .mapToPair(Tuple2::swap) .sortByKey(false) .map(Tuple2::_2) .take(amount); lines.map(_.toLowerCase()) .flatMap("w+".r.findAllIn(_)) .filter(!garbage.contains(_)) .map((_,1)).reduceByKey(_+_) .sortBy(_._2,ascending = false) .take(amount)
  • 74. Говно ваша JAVA 8 Все персонажи вымышлены, любое сходство с реальными людьми случайно!
  • 77. Dataframes – since 1.3 • DataFrame is a distributed collection of data organized into named columns • Под капотом RDD, но там много оптимизаций • Датафрэймы требуют меньше памяти, если их умно использовать • Можно создать из hive таблиц, json подобных файлов, обычных RDD, внешних баз данных, и из всего имеющего структуру • Имеет очень широкий DSL • Cвязан с SqlContext
  • 78. Dataframes methods and functions Agg, columns, count, distinct, drop, dropDuplicates, filter groupBy, orderBy, registerTable, schema, show, select, where, withColumn
  • 79. Немного методов Датафрэймов Agg, columns, count, distinct, drop, dropDuplicates, filter groupBy, orderBy, registerTable, schema, show, select, where, withColumn dataFrame.registerTempTable("finalMap"); DataFrame frame = sqlContext.sql("select cl_id, cl_grp_id, dk_org_snw, dk_org_hnw, dk_org_cnp, dk_dir, dk_dat, DK_TIM_HR as dk_tim_hr, dk_spe, dk_sgt, dk_pet, dk_sgs, dk_sbp,n" + "SUM(slu_atpt) slu_atpt, SUM(slu_succ) slu_succ, SUM(slu_fail) slu_fail, SUM(slu_dly) slu_dlyn" + "FROM finalMap f join tdtim t on f.dk_tim = t.DK_TIMn" + "WHERE dk_pet IN (1, 4)n" + "group by cl_id, cl_grp_id, dk_org_snw, dk_org_hnw, dk_org_cnp, dk_dir, dk_dat, DK_TIM_HR, dk_spe, dk_sgt, dk_pet, dk_sgs, dk_sbp").toDF();
  • 80. Не говорите ему про SqlContext
  • 81. Почему я не люблю sql нигде DataFrame dataFrame1 = sqlContext.sql("select tdmco.CL_ID as cl_id, n" + "tttmdcl.CL_GRP_ID as cl_grp_id, n" + "tttdpet.DK_PET as dk_pet, n" + "tttdsgt.DK_SGT as dk_sgt, n" + "tttdsgs.DK_SGS as dk_sgs, n" + "tttddir.DK_DIR as dk_dir, n" + "tttdorg.DK_ORG as dk_org_cnp,n" + "ttcase when data.INBOUND_IND = 0 then tdorg.DK_ORG when data.INBOUND_IND = 1 then tdmco.CL_ID end as dk_org_hnw,n" + "ttcase when data.INBOUND_IND = 1 then tdorg.DK_ORG when data.INBOUND_IND = 0 then tdmco.CL_ID end as dk_org_snw,n" + "tttddat.DK_DAT as dk_dat,n" + "tttdtim.DK_TIM as dk_tim,n" + "ttcast(case when spe1.DK_SPE is not null then spe1.DK_SPE when spe2.DK_SPE is not null then spe2.DK_SPE when spe3.DK_SPE is not null then spe3.DK_SPE else 0 end as big "ttcast(-999 as bigint) as dk_sgl, n" + "ttcast(-999 as bigint) as dk_adt,n" + "ttcast(0 as bigint) as dk_sbp,n" + "ttdata.IMSI as dd_imsi,n" + "ttMSISDN as dd_msisdn_min, n" + "ttMSC as dd_msc, n" + "ttHLR as dd_hlr, n" + "ttSGSN_GT as dd_sgsn_gt, n" + "ttSGSN_IP as dd_sgsn_ip,n" + "ttcast(1 as bigint) as slu_atpt,n" + "ttcast(case when data.STATUS = 'OK' then 1 else 0 end as bigint) as slu_succ,n" + "ttcast(case when data.STATUS = 'Reject' then 1 else 0 end as bigint) as slu_fail,n" + "ttcast(((unix_timestamp(substring(data.TIME_END,1,19))*1000)+(substring(data.TIME_END,21,3)))-((unix_timestamp(substring(data.TIME,1,19))*1000)+(substring(data.TIME,21 "ttdata.STATUS as statusn" + "tt-- first_value(tmdsbsprf.PRF_ID) OVER (PARTITION BY tdmco.CL_ID,data.IMSI ORDER BY length(tmdsbsprf.MATCH_STR) desc,tmdsbsprf.MATCH_START) AS sbs_prf_if,n" + "from data left join tdmco on (data.OWNER_CODE=tdmco.MCO_TAP_CD)n" + "left join tmdcl on (tdmco.CL_ID=tmdcl.CL_ID)n" + "left join tdpet on (data.OPCODE=tdpet.PET_CD)n" + "left join tdsgt on (case when data.OPCODE = 2 then 'C' when data.OPCODE = 23 then 'P' end = tdsgt.SGT_CD)n" + "left join tdsgs on (case when data.STATUS = 'OK' then 'S' when data.STATUS = 'Reject' then 'F' end = tdsgs.SGS_CD)n" + "left join tddir on (case when data.INBOUND_IND = 0 then 'V' when data.INBOUND_IND = 1 then 'O' end = tddir.DIR_CD)n" + "left join tdorg on (data.OP_ID = tdorg.ORG_TAP_CD)n" + "left join tddat on (to_date(data.TIME) = to_date(tddat.DAT))n" + "left join tdtim on (substring(data.TIME,12,8) = tdtim.TIM)n" + "left join tdspe as spe1 on (case when data.STATUS = 'Reject' and data.MAP_ERR is null and TCAP_ERR is null then 255 end = spe1.SPE_CD and spe1.SPE_CAT = 'MAP')n" + "left join tdspe as spe2 on (case when data.TCAP_ERR is null or (data.MAP_ERR is not null and data.TCAP_ERR is not null) then data.MAP_ERR end = spe2.SPE_CD and spe2.SPE_ "left join tdspe as spe3 on (case when data.MAP_ERR is null and data.TCAP_ERR is not null then data.TCAP_ERR end = spe3.SPE_CD and spe3.SPE_CAT = 'TCAP')n" + "-- left join tmdsbsprf on (tdmco.CL_ID = tmdsbsprf.org_tech_id and SUBSTR(data.IMSI, tmdsbsprf.MATCH_START, LENGTH(tmdsbsprf.MATCH_STR)) = tmdsbsprf.MATCH_STR and to_dat
  • 82. Dataframes methods and functions • abs, cos, asin, isnull, not, rand, sqrt, when, expr, bin, atan, ceil, floor, factorial, greatest, least, log, log10, pow, round, sin, toDegrees, toRadians, md5, ascii, base64, concat, length, lower, ltrim, unbase64, repeat, reverse, split, substring, trim, upper, datediff, year, month, hour, last_day, next_day, dayofmonth, explode, udf
  • 83. Dataframes methods and functions • abs, cos, asin, isnull, not, rand, sqrt, when, expr, bin, atan, ceil, floor, factorial, greatest, least, log, log10, pow, round, sin, toDegrees, toRadians, md5, ascii, base64, concat, length, lower, ltrim, unbase64, repeat, reverse, split, substring, trim, upper, datediff, year, month, hour, last_day, next_day, dayofmonth, explode, udf
  • 85. Миф четвёртый • Датафрэймы можно использовать только для файлов со схемой
  • 86. Функций много, но если надо свою? @Component public class GarbageFilter implements UDF1<String,Boolean> { @Value("${garbage}") private String[] garbage; public String udfName(){return "notGarbage";} @Override public Boolean call(String word) throws Exception { return !Arrays.asList(garbage).contains(word); } }
  • 87. Как пользоваться UDF функциями? @Service public class PopularWordsResolverWithUDF { @Autowired private GarbageFilter garbageFilter; @Autowired private SQLContext sqlContext; @PostConstruct public void registerUdf(){ sqlContext.udf().register(garbageFilter.udfName(),garbageFilter, DataTypes.BooleanType); } public List<String> mostUsedWords(DataFrame dataFrame, int amount) { DataFrame sorted = dataFrame.withColumn("words", lower(column("words"))) .filter(callUDF(garbageFilter.udfName(),column("words")))…
  • 88. Итоги и выводы • Hadoop нуждается в Спарке, а не наоборот • Можно отлично обойтись без Скалы • Можно использовать привычный вам подход: • Инверсия контроля, Spring, Шаблоны проектирования • Можно прекрасно писать тесты • Можно везде (ну почти) пользоваться Датафрэймами • И главное:
  • 89. Pink Floyd не попса!!!
  • 90. Спасибо Баруху и Егору за предоставленные фото
  • 91. Спасибо моей дочке за предоставленные тексты песен
  • 92. Все остальные персонажи вымышлены, любое сходство с реальными людьми случайно!