일래스틱서치에서 저장된 index가 월별일 때 특정 월만 검색하고 싶다면 body나 request에 포함할 수 있다.


curl -X GET "http://inhouse.google.com:9200/reqlog-*/_search?ignore_unavailable=true" -H 'Content-Type: application/json' -d'

{

    "query": {

        "terms" : {

            "_index" : ["reqlog-2019-09, reqlog-2019-10"]

        }

    }

}'


또는

curl -X GET http://inhouse.google.com:9200/reqlog-*/_search/reqlog-2019-09, reqlog-2019-10/_search?ignore_unavailable=true

{

    "query": {

        ...

    }

}



 ignore_unavailable의 기본 값은 false이다. 검색시 인덱스가 없으면 에러가 발생한다.
 true로 설정해서 검색시 인덱스 없으면 에러가 발생하지 않는다.



Posted by '김용환'
,


http://www.google.com/////// 이란 문자열에서 뒤의 /를 모두 빼려면 어떻게 할까?


파이썬에서는 아주 간단히 해결할 수 있다.


"http://www.google.com/get/order/".strip("/")

->http://www.google.com/get/order


"http://www.google.com/get/order////".strip("/")

->http://www.google.com/get/order


Posted by '김용환'
,

spark / sbt 1.3.0-RC1를 사용 중이다. 


sbt test를 실행해

테스트 코드를 모두 완료하고 종료할 때 Java의 ShutdownHookManager에서 Can not access 또는 Can not load 예외가 발생할 수 있다. 

이는 jvm shutdown하면서 shutdownhook에서 정리할 내용보다 먼저 자원이 정리되면서 발생하는 문제이다. 



$ sbt test 

...

INFO: Illegal access: this web application instance has been stopped already.  Could not load org.apache.hadoop.util.ShutdownHookManager$2.  The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.

java.lang.IllegalStateException

  at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1600)

  at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)

  at org.apache.hadoop.util.ShutdownHookManager.getShutdownHooksInOrder(ShutdownHookManager.java:124)

  at org.apache.hadoop.util.ShutdownHookManager$1.run(ShutdownHookManager.java:52




sbt 실행시 아래와 같은 설정을 추가한다. 더 이상 해당 에러는 발생하지 않는다. 

-Dsbt.classloader.close=false


'scala' 카테고리의 다른 글

[scala] jackson, ujson  (0) 2019.10.04
[펌] [spark] spark graceful하게 종료하는 방법  (0) 2019.10.02
[scala] 문자열의 값에 해당하는 enum 타입 얻어오기  (0) 2019.09.20
[sbt] 1.3.0  (0) 2019.09.06
scala cats 공부 자료.  (1) 2019.06.18
Posted by '김용환'
,



How to get applicationId of Spark application deployed to YARN in ...


https://spark.apache.org/docs/2.3.0/api/java/org/apache/spark/SparkContext.html


applicationId

public String applicationId()
A unique identifier for the Spark application. Its format depends on the scheduler implementation. (i.e. in case of local spark app something like 'local-1433865536131' in case of YARN something like 'application_1433865536131_34483' in case of MESOS something like 'driver-20170926223339-0001' )




val appId = spark.sparkContext.applicationId


Posted by '김용환'
,


Spark/Scala 작업을 하다 아래와 같은 에러가 발생했다.

Unsupported literal type class scala.collection.immutable.$colon$colon List(0, 1)





원인은 아래 문 isin 메소드 때문이다.


(아래 코드는 df1, df2라는 데이터 프레임에 대해 df1-df2를 하기 전에 
df1의 null 부분을 0으로 변경해, 쉽게 df1-df2(차집합)을 얻기 위한 코드이다)

import spark.implicits._

val validCode = List(0, 1)

var df1 =
Seq(
("1", "r1c2", null),
("2", "r2c2", new Integer(1)),
("3", "r2c2", new Integer(3))
).toDF("id", "c1", "c2")

val df2 =
Seq(
("1", "r1c2", new Integer(0)),
("2", "r2c2", new Integer(2))
).toDF("id", "c1", "c2")

df1 = df1.withColumn("c2", when($"c2".isin(validCode).isNull, 0) .otherwise($"c2"))
val df3 = df1.except(df2)
df3.show(5)



org.apache.spark.sql.Column.isin 메소드는 다음과 같다. Any 타입의 variable argument 타입을 추가해야 한다. 

def isin(list : scala.Any*)



그래서 에러 코드를 아래와 같이 변경하면.. 컴파일러가 인식하지 못한다.

isin(validCode) ->

isin(validCode:Any*)


이럴 때는 Any* 타입이 아니라 _* 으로 변경한다.


df1 = df1.withColumn("c2", 
         when($"c2".isin(validCode:_*).isNull, 0)
          .otherwise($"c2"))


코드는 잘 실행된다.


_*를 스칼라에서 Type Ascription(annotation으로 쉽게 표기하는 문법)에 필요한 문법으로서

Sugar Syntax로 말하기도 한다. 




isin(validCode:_*)

은 아래와 같이 사용해도 된다.

isInCollection(validCode)


Posted by '김용환'
,


인덱스를 복사하려면 reindex 커맨드를 사용한다.



curl -X POST http://gift-es-dev.daumkakao.io:9200/_reindex  -H 'Content-Type: application/json' -d'

{

  "source": {

    "index": "google_items"

  },

  "dest": {

    "index": google_item_test"

  }

}'







Posted by '김용환'
,



Mac OS에서 docker-compose를 실행하다 다음 에러가 발생했다. 



Credentials store docker-credential-osxkeychain exited with "User interaction is not allowed." 


해결 방법


- 첫 번째 작업

최신 docker로 업그레이드 한다.



- 두 번째 작업


menu bar -> preferences -> "Securely store docker logins in macOS keychain"의 체크박스가 on되어 있는데. off로 변경한다.


- 세 번째 작업

예전 docker 설정 때문에 이슈가 있으니 아래와 같이 변경한다.


cat ~/.docker/config.json

{

  "experimental" : "disabled",

  "stackOrchestrator" : "swarm",

  "auths" : {


  },

  "credsStore" : ""

}



그래도 안되면 재부팅해본다. 

Posted by '김용환'
,


파이프라인 프로세서(pipeline processor)를 사용하면 특정 인덱스로 저장 또는 검색할 수 있다. 


먼저 템플릿을 저장한다. 


$ curl -X PUT "localhost:9200/_template/reglog?pretty" -H 'Content-Type: application/json' -d'

{

   "template": "reqlog_*",

   "mappings": {

       "properties": {

         "id": {

           "type": "long"

        },

        "date1": {

           "type": "date"

        }

    }

  }

}

'


파이프라인을 등록한다. 파이프라인을 월별로 저장하기 위해 설정한 부분은 아래와 같다.

 
$ curl -X PUT "http://localhost:9200/_ingest/pipeline/reqlog-monthly-index" -H 'Content-Type: application/json' -d'

{

  "description": "monthly index naming for reqlog",

  "processors" : [

    {

      "date_index_name" : {

        "field" : "date1",

        "index_name_prefix" : "reqlog_",

        "index_name_format" : "yyyy-MM",

        "date_rounding" : "M"

      }

    }

  ]

}'



파이프에 템플릿을 저장하는 방식을 사용해 데이터를 인덱스에 저장한다. 


$ curl -X PUT "localhost:9200/reqlog/_doc/2?pipeline=reqlog-monthly-index&pretty" -H 'Content-Type: application/json' -d'

{

  "date1" : "2019-01-25T20:16:55.000Z"

}

'


데이터를 확인하면 제대로 있다.  이렇게 월별 인덱스에 저장한다. 


$ curl http://localhost:9200/reqlog_2019-01/_doc/2



이렇게 다르게 저장해도 제대로 데이터를 검색할 수 있다.



$ curl -X PUT "localhost:9200/reqlog/_doc/4?pipeline=reqlog-monthly-index&pretty" -H 'Content-Type: application/json' -d'

{

  "date1" : "2019-02-25T20:16:55.000Z"

}

'

$ curl http://localhost:9200/reqlog_2019-02/_doc/4





연도별 인덱스를 생성하려면 다음과 같이 파이프라인을 정의할 수 있다. 


curl -X PUT "http://localhost:9200/_ingest/pipeline/reqlog_yearly_index" -H 'Content-Type: application/json' -d'

{

  "description": "yearly index naming for reqlog_yearly",

  "processors" : [

    {

      "date_index_name" : {

        "field" : "date1",

        "index_name_prefix" : "reqlog_yearly_",

        "index_name_format" : "yyyy",

        "date_rounding" : "y"

      }

    }

  ]

}'






그런데 문제는 UTC 기준으로 데이터를 인덱싱하지 못한다는 점이다.


timezone: +09:00을 사용하면 잘 동작한다. 


$ curl -X PUT "http://localhost:9200/_ingest/pipeline/reqlog-monthly-index" -H 'Content-Type: application/json' -d'

{

  "description": "monthly index naming for reqlog",

  "processors" : [

    {

      "date_index_name" : {

        "field" : "date1",

        "index_name_prefix" : "reqlog_",

        "index_name_format" : "yyyy-MM",

        "date_rounding" : "M",

        "timezone": "+09:00"

      }

    }

  ]

}'




만약 java timemillis 타입으로 데이터를 저장했다면 

date_formats의 값을 [UNIX_MS]로 변경한다.


$ curl -X PUT "http://localhost:9200/_ingest/pipeline/reqlog-monthly-index" -H 'Content-Type: application/json' -d'

{

  "description": "monthly index naming for reqlog",

  "processors" : [

    {

      "date_index_name" : {

        "field" : "date1",

        "index_name_prefix" : "reqlog_",

        "index_name_format" : "yyyy-MM",

        "date_formats"      : [ "UNIX_MS" ],

        "date_rounding" : "M",

        "timezone": "+09:00"

      }

    }

  ]

}'






참고 자료

https://github.com/elastic/elasticsearch/blob/7.4/modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/DateIndexNameFactoryTests.java

Posted by '김용환'
,


스칼라에서 enum 타입에 맞는 문자열 값을 찾아 enum을 리턴하는 메소드가 필요하다.

이럴 때는 사용할 만한 메소드로 filter와 find가 적당하다.

filter는 List 배열을 리턴하기에 마땅치 않고 find가 적당한 것 같다.


public enum TestEnum {
A("a"),
B("b");

private String value;

private TestEnum(String value) {
this.value = value;
}

public String getValue() {
return value;
}
}





object Test {

def main(args: Array[String]): Unit = {

val wrongEnumType : String = "xxx"

val wrong = TestEnum.values().find(e => wrongEnumType.equals(e.getValue))

if (wrong.isDefined) {
println(wrong)
} else {
println("wrong enum type")
}

}
}


Posted by '김용환'
,



커맨드

 docker-compose -f docker-compose.yml up ${container_name}


예)

 docker-compose -f docker-compose.yml up  rabbitmq



Posted by '김용환'
,