Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Spark Streaming Snippets
Search
AGAWA Koji
March 14, 2016
Programming
1.1k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Spark Streaming Snippets
AGAWA Koji
March 14, 2016
More Decks by AGAWA Koji
See All by AGAWA Koji
Software Architecture in an AI-Driven World
atty303
79
49k
PipeCDプラグインへの期待 / Anticipating PipeCD Plugins
atty303
0
140
EmscriptenでC/C++アプリをWASM化してブラウザで動かしてみた
atty303
0
700
良いソフトウェアとコードレビュー / Good software and code review
atty303
38
19k
Scala + Caliban で作るGraphQL バックエンド / Making GraphQL Backend with Scala + Caliban
atty303
0
620
Scala.jsとAndroidでドメイン層を共有しよう / Scala.js and Android
atty303
0
840
もう一つのビルドツール mill で作る Docker イメージ / Build docker image with mill the yet another build tool
atty303
2
2.6k
Case of Ad Delivery System is Implemented by Scala and DDD
atty303
4
3.7k
ログのメトリックを取ってみる話
atty303
0
1.1k
Other Decks in Programming
See All in Programming
動作中のプログラムの中身をリアルタイムに覗く / Realtime Debugger for CSharp with Roslyn
prota
1
1.8k
Agents on Rails - Rails at Scale 2026
irinanazarova
0
350
Workers Cache を知る
syumai
0
340
更なる可用性を求めて、5年間運用したKotlinのアプリケーションをGoでリプレイスする話
ken_tunc
0
450
[ハンズオン]AIへの指示だけで「五目並べ」を作ってみよう
satoshi256kbyte
1
350
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
34
16k
When benchmarks go bad - what I learned from measuring performance wrong
hollycummins
0
190
UPDATE をやめる — EF Core でマスタをバージョン管理する
panda728
PRO
0
1.1k
Agentic Software Factoryに、すごく賢いIF文を。 / super smart IF statement into the Agentic Software Factory.
rkaga
8
2k
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
490
mrbgem 三角測量 開発
ogom
0
210
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
160
Featured
See All Featured
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
Product Roadmaps are Hard
iamctodd
55
13k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.4k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
1k
Navigating Team Friction
lara
192
16k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
390
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
390
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
1k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
2
2.2k
The Curse of the Amulet
leimatthew05
3
15k
Transcript
Spark Streaming Snippets @a#y303
ࠓ·Ͱ࡞ͬͨ Spark Streaming ΞϓϦ • rtg -- ϦΞϧλΠϜϦλή༻σʔλੜ • pixelwriter
-- Dynamic Crea4ve ༻ϚʔΫσʔλॻ͖ࠐΈ • feedsync -- ϑΟʔυಉظ • segment:elas4c -- ϦΞϧλΠϜηάϝϯτԽ • (logblend -- ҟͳΔΠϕϯτϩάͷ Join)
͜ΕΒͷΞϓϦ͔Βదʹڞ༗͢Δͱخͦ͠͏ͳͱ͜ ΖΛൈ͍ͯΈͨ • SparkBoot • Cron • UpdatableBroadcast • Connector
• SparkStreamingSpec
SparkBoot h"ps:/ /gist.github.com/a"y303/c83f3c8cb8a930951be0 • Spark ΞϓϦͷ main ࣮ • SparkContext
/ StreamingContext Λఏڙ͢Δ • Configura4on ཧ • spark-submit ͷ --files Ͱ applica4on.conf ΛૹͬͯΧελ ϚΠζ
όονͷ߹ object TrainingBatchApp extends SparkBatchBoot { val appName = "TrainingBatchApp"
override def mkApp(sc: SparkContext, args: Array[String]): SparkApp = new TrainingBatchApp(sc, appConfig) } class TrainingBatchApp( sc: SparkContext, appConfig: Config) extends SparkApp { def run(): Try[Int] = Try { 0 } }
ετϦʔϛϯάͷ߹ object PredictStreamingApp extends SparkStreamingBoot { val appName = "PredictStreamingApp"
override val checkpointPath: String = "app.training.streaming.checkpoint-path" override val batchDurationPath: String = "app.training.streaming.batch-duration" override def mkApp(sc: SparkContext, ssc: StreamingContext, args: Array[String]): SparkApp = new PredictStreamingApp(ssc, batchDuration, appConfig) } class PredictStreamingApp( ssc: StreamingContext, appConfig: Config) extends SparkApp { val sparkContext = ssc.sparkContext def run(): Try[Int] = Try { 0 } }
Cron తͳ͜ͱΛΔ • batch-dura+on ΑΓִ͍ؒͰఆظ࣮ߦ͍ͨ͠ॲཧ͕͋Δ • ֎෦σʔλετΞ͔ΒಡΜͰ͍ΔϚελσʔλͷϦϑϨογϡ ͳͲ
def repeatedly(streamingContext: StreamingContext, interval: Duration) (f: (SparkContext, Time) => Unit):
Unit = { // τϦΨʔΛੜ͢Δ DStream val s = streamingContext.queueStream( mutable.Queue.empty[RDD[Unit]], oneAtATime = true, defaultRDD = streamingContext.sparkContext.makeRDD(Seq(()))) .repartition(1) s.window(s.slideDuration, interval) .foreachRDD { (rdd, time) => f(rdd.context, time) rdd.foreach(_ => ()) } }
͍ํ repetedly(streamingContext, Durations.seconds(300)) { (sc, time) => // @driver: 5
ຖʹ࣮ߦ͢Δॲཧ }
ߋ৽Մೳͳ Broadcast • Streaming ͕ಈ͖࢝Ίͨޙʹ Broadcast Λߋ৽͍ͨ͠ • ୯ͳΔ Broadcast
Λอ࣋͢Δϥούʔ
/** * ͷߋ৽(࠶ϒϩʔυΩϟετ)͕Մೳͳ Broadcast * * https://gist.github.com/Reinvigorate/040a362ca8100347e1a6 * @author Reinvigorate
*/ case class UpdatableBroadcast[T: ClassTag]( @transient private val ssc: StreamingContext, @transient private val _v: T) { @transient private var v = ssc.sparkContext.broadcast(_v) def update(newValue: T, blocking: Boolean = false): Unit = { v.unpersist(blocking) v = ssc.sparkContext.broadcast(newValue) } def value: T = v.value private def writeObject(out: ObjectOutputStream): Unit = { out.writeObject(v) } private def readObject(in: ObjectInputStream): Unit = { v = in.readObject().asInstanceOf[Broadcast[T]] } }
͍ํ def loadModel(): Model = ??? val ub: UpdatableBroadcast[Model] =
UpdatableBroadcast(streamingContext, loadModel()) StreamingUtil.repeatedly(streamingContext, refreshInterval) { (_, _) => ub.update(loadModel()) } dstream.foreachRDD { rdd => val model = ub.value // use model }
֎෦ଓͷநԽ • Spark Ͱ֎෦ϦιʔεʹΞΫηε͢Δͱ͖ɺݸʑͷ Executor ͕ ଓΛҡ࣋͢Δඞཁ͕͋Δ • Driver ͔Β
Executor ʹʮଓͦͷͷʯΛૹ৴͢Δ͜ͱͰ͖ ͳ͍ • ʮଓ͢Δํ๏ʯΛ Connector trait ͱͯ͠நԽ͍ͯ͠Δ
trait Connector[A] extends java.io.Closeable with Serializable { def get: A
def close(): Unit def using[B](f: A => B): B = f(get) }
case class PoolAerospikeConnector(name: Symbol, config: AerospikeConfig) extends Connector[AerospikeClient] { def
get: AerospikeClient = PoolAerospikeConnector.defaultHolder.getOrCreate(name, mkClient) def close(): Unit = PoolAerospikeConnector.defaultHolder.remove(name)( AerospikeConnector.aerospikeClientClosable) private val mkClient: () => AerospikeClient = () => new AerospikeClient(config.clientPolicy.underlying, config.asHosts:_*) } object PoolAerospikeConnector { private val defaultHolder = new DefaultResourceHolder[AerospikeClient] }
case class ScalikeJdbcConnector(name: Symbol, config: Config) extends Connector[Unit] { def
get: Unit = { if (!ConnectionPool.isInitialized(name)) { // Load MySQL JDBC driver class Class.forName("com.mysql.jdbc.Driver") ConnectionPool.add(name, config.getString("url"), config.getString("user"), config.getString("password")) } } def close(): Unit = ConnectionPool.close(name) }
case class KafkaProducerConnector[K :ClassTag, V :ClassTag]( name: Symbol, config: java.util.Map[String,
AnyRef]) extends Connector[ScalaKafkaProducer[K, V]] { def get: ScalaKafkaProducer[K, V] = KafkaProducerConnector.defaultHolder.getOrCreate(name, mkResource) .asInstanceOf[ScalaKafkaProducer[K, V]] def close(): Unit = KafkaProducerConnector.defaultHolder.remove(name)( KafkaProducerConnector.kafkaProducerClosable) private val mkResource = () => { val keySer = mkDefaultSerializer[K](ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG) val valueSer = mkDefaultSerializer[V](ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG) new ScalaKafkaProducer[K, V]( new KafkaProducer[K, V](config, keySer.orNull, valueSer.orNull)) } private def mkDefaultSerializer[A :ClassTag](configKey: String): Option[Serializer[A]] = { if (!config.containsKey(configKey)) { implicitly[ClassTag[A]].runtimeClass match { case c if c == classOf[Array[Byte]] => Some(new ByteArraySerializer().asInstanceOf[Serializer[A]]) case c if c == classOf[String] => Some(new StringSerializer().asInstanceOf[Serializer[A]]) case _ => None } } else None } }
Spark Streaming ͷςετ h"ps:/ /gist.github.com/a"y303/18e64e718f0cf3261c0e
class CountProductSpec extends SpecWithJUnit with SparkStreamingSpec { val batchDuration: Duration
= Duration(1000) "Count" >> { val (sourceQueue, resultQueue) = startQueueStream[Product, (Product, Long)] { inStream => // ςετରͷ Streaming ॲཧ CountProduct(inStream).run(sc) } // ೖྗΩϡʔʹςετσʔλΛೖ͢Δ sourceQueue += sc.parallelize(Seq( Product(1, "id"), Product(1, "id"), Product(2, "id"))) // ࣌ؒΛਐΊΔ advance() // ग़ྗ͞ΕΔσʔλΛςετ͢Δ resultQueue.dequeue must eventually(contain(exactly( Product(1, "id") -> 2L, Product(2, "id") -> 1L ))) } }