scala-guice는 google-guice를 이용해 scala quill에 맞게 inject를 구현한 간단 코드이다.


libraryDependencies ++= Dependencies.guice


val guice = Seq(
"com.google.inject" % "guice" % "4.2.2",
"com.google.inject.extensions" % "guice-assistedinject" % "4.2.2",
"net.codingwell" %% "scala-guice" % "4.2.2"
)




scala quill 를 사용할 때 데이터 타입 관련해서 Encoder/Decoder로 사용할 Implicits를 구현한다.


package com.google.quill

import java.util.Date

import io.getquill.MappedEncoding
import org.joda.time.DateTime

object Implicits {
implicit val dateTimeDecoder = MappedEncoding[Date, DateTime](Decoders.fromDateField)
implicit val dateTimeEncoder = MappedEncoding[DateTime, Date](_.toDate)
}

object Decoders {
def fromDateField(date: Date): DateTime = {
new DateTime(date)
}
}




데이터베이스에서 사용하는 Orders 클래스를 정의한다.



package com.google.datalake.dao.shopping

import org.joda.time.DateTime

case class Orders(
id: Long,
payment_id: Long,
refund_id: Option[Long],
channel_id: Long,
seller_id: Long,
buyer_id: Option[Long],
buyer_user_id: Long, #...
)



properties 정보

orderDB.dataSourceClassName=com.mysql.jdbc.jdbc2.optional.MysqlDataSource
orderDB.dataSource.url="jdbc:mysql://test.google.com:3306/buy?useTimezone=true&serverTimezone=UTC&characterEncoding=UTF-8"
orderDB.dataSource.user=xxx
orderDB.dataSource.password=xxx
orderDB.dataSource.cachePrepStmts=true
orderDB.dataSource.prepStmtCacheSize=250




실제 Inject 중심 클래스를 정의한다. google-guice의 AbstractModule를 상속하고 scala-guide의 ScalaModule를 믹싱한 DataBaseModule을 정의한다. 

package com.google.datalake.db.modules

import com.google.inject._
import com.google.datalake.db.SelectOrderDB
import io.getquill.{MysqlJdbcContext, SnakeCase}
import net.codingwell.scalaguice.ScalaModule
import com.google.inject.AbstractModule

class DataBaseModule extends AbstractModule with ScalaModule {

override def configure(): Unit = {
bind(classOf[SelectOrderDB]).asEagerSingleton()
}

@Provides
def provideDataBaseSource(): MysqlJdbcContext[SnakeCase] = {
new MysqlJdbcContext(SnakeCase, "orderDB")
}
}


quill을 이용한 DAO 코드이다. MysqlJdbcContext를 inject해서 사용할 수 있게 한다.


package com.google.datalake.db

import com.google.inject.Inject
import com.google.datalake.dao.shopping.Orders
import io.getquill.{MysqlJdbcContext, SnakeCase}

class SelectOrderDB @Inject()(val ctx: MysqlJdbcContext[SnakeCase]) {

import ctx._

def findById(id: Long) = {
val q = quote {
query[Orders].filter(_.id == lift(id))
}
ctx.run(q)
}

def findByIds(ids: List[Long]): Unit = {
val q = quote {
query[Orders]
.filter(p => liftQuery(ids).contains(p.id))
}
ctx.run(q)
}
}


실제 테스크 코드는 다음과 같다.

package com.google.datalake.db

import com.google.inject.Guice
import com.google.datalake.db.modules.DataBaseModule
import org.scalatest.FunSuite

class SelectOrderDBTest extends FunSuite {

val injector = Guice.createInjector(new DataBaseModule()).getInstance(classOf[SelectOrderDB])
val selectOrderDB = injector.asInstanceOf[SelectOrderDB]

test("find by id") {
val row = selectOrderDB.findById(71721303)

println(row)
}

}







Posted by '김용환'
,


아마존의 Redshift와 구글의 Bigtable을 고려한 적이 있었는데..


"빅 데이터를 지탱하는 기술"이라는 책에서 잠깐 내용을 소개하자면..




중요한 차이점이 하나 있는데. Redshift는 전용(dedicated)인 반면, Bigtable은 멀티테넌트 기반의 공유(shared) 자원 기반이라는 점이다.


따라서 Redshift는 다른 사용자가 사용할 없어서 성능이 안정적이다. 항상 일정한 성능이 나온다.


반면, BigTable은 데이터를 분산하기 때문에 고속화를 실현한다. 다수의 디스크에 데이터가 분산되는 형태를 갖는다. (muti-tenancy 구조이다.)




https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html



https://cloud.google.com/blog/products/gcp/bigquery-under-the-hood


Posted by '김용환'
,