'뱅뱅이론' 


남들이 얘기하길래 찾아본 이론이다.


역시 내 생각과 실제는 다른 것 같다.  



http://www.ddanzi.com/ddanziNews/141355230



http://news.donga.com/3/all/20130730/56737249/1



http://www.fashionchannel.co.kr/main/news.php?table=papernews&query=view&uid=5566

Posted by 김용환 '김용환'

댓글을 달아 주세요


pyenv 정리하다가 실수로 .pyenv를 삭제할 수 있다. 

pip 실행시 아래와 같이 로그가 나오면...


/Users/samuel.kim/.pyenv/shims/pip: line 21: /usr/local/Cellar/pyenv/1.2.7/libexec/pyenv: No such file or directory

/Users/samuel.kim/.pyenv/shims/pip: line 21: /usr/local/Cellar/pyenv/1.2.7/libexec/pyenv: No such file or directory

-bash: /Users/samuel.kim/.spark/venv/bin/python3: No such file or directory

-bash: /Users/samuel.kim/.spark/venv/bin/activate: No such file or directory





 pyenv rehash를 실행하면 pyenv 환경이 제대로 되고 위 에러가 발생하지 않는다.

Posted by 김용환 '김용환'

댓글을 달아 주세요


늘 자주 사용하긴 하지만 


kafka-01.internal.google.com에서 kafka-20.internal.google.com까지의 ip 주소를 얻고 싶다면 



number=0; for i in $(seq 1 20); do if [ $i -le 9 ]; then number=0$i ; else number=$i  ; fi ; ping -c1 -t 1 kafka-$number.internal.google.com  ; done



결과는 나오지만 지저분하게 나오려면 다음처럼 awk를 써서 처음 라인의 호스트와 ip만 나오게 한다.




number=0; for i in $(seq 1 20); do if [ $i -le 9 ]; then number=0$i ; else number=$i  ;fi ; ping -c1 -t 1 kafkatest-$numberr.internal.google.com | awk 'NR==1{print $2$3 ; exit}'  ; done



kafkatest-17.internal.google.com(1.1.1.1

...

Posted by 김용환 '김용환'

댓글을 달아 주세요


mysql에서 여러 개의 master의 데이터를 하나의 slave에 저장할 때 multi-source replication 기법을 사용할 수 있다.

mysql replication과 channel 개념 배우는 자료이다.

Open source India - MySQL Labs: Multi-Source Replication from Shivji kumar Jha


https://dev.mysql.com/doc/refman/5.7/en/replication-multi-source-tutorials.html


Posted by 김용환 '김용환'

댓글을 달아 주세요




google guice는 dependency inject 경량 프레임워크이다.


이를 scala(spark)에서 사용하려면 여러 방법이 있겠지만 내가 아는 방법은 2가지이다.



1. scala-guice를 사용한다.


https://github.com/codingwell/scala-guice


실제로 scala-guice를 사용해 구현해보니 경량스럽게 개발이 가능하다.



google guice와 scala-guice 개념을 이해하는데 도움되는 글


https://www.tutorialspoint.com/guice/guice_provides_annotation.htm


https://www.journaldev.com/2403/google-guice-dependency-injection-example-tutorial


https://medium.freecodecamp.org/a-hands-on-session-with-google-guice-5f25ce588774


AbstractModule을 상속하지 않아도 쉽게 구현 가능하다.

그리고 복잡한 형태의 Module을 사용할 수 있다.






2. finatra의 TwitterModule를 사용한다.


TwitterModule은 scala-guice/google-guice 기반이고 finatra 관련 프로젝트라서 엄청난 dependency를 갖고 있다. 


https://twitter.github.io/finatra/user-guide/getting-started/modules.html#module-configuration-in-servers



TwitterModule은 google-guice의 AbstraceModule을 구현한 것으로 무겁지만(너무 많은 dependency) 쉬운 개발이 가능하고 훨씬 기능이 많다.







Posted by 김용환 '김용환'

댓글을 달아 주세요



UserWarning: The psycopg2 wheel package will be renamed from release 2.8 에러가 나면



psycopg2-binary를 설치하면 에러가 사라진다.



pip install psycopg2-binary





Posted by 김용환 '김용환'

댓글을 달아 주세요




vagrant의  multi-VM environment 설정 예시이다.




# -*- mode: ruby -*-

# vi: set ft=ruby :


# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!

VAGRANTFILE_API_VERSION = "2"


Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|


  config.ssh.insert_key = false


  config.vm.define 'db' do |db|


    db.vm.box = "ubuntu/bionic64"

    db.vm.network "private_network", ip: "192.168.33.11"

    db.ssh.forward_agent = true


    db.vm.provider "virtualbox" do |vb|

      vb.customize ["modifyvm", :id, "--memory", "1024"]

    end

  end


  config.vm.define 'web' do |web|


    web.vm.box = "ubuntu/bionic64"

    web.vm.network "private_network", ip: "192.168.33.10"

    web.ssh.forward_agent = true


    web.vm.provider "virtualbox" do |vb|

      vb.customize ["modifyvm", :id, "--memory", "1024"]

    end


    web.vm.provision "ansible" do |ansible|

      ansible.limit = 'all'

      ansible.playbook = "mezzanine-across-hosts.yml"

    end


  end


end





vagrant ssh db 또는 vagrant ssh web 이렇게 접근할 수 있다. 

Posted by 김용환 '김용환'

댓글을 달아 주세요







profile_tasks 플러그인을 사용하면


각 태스크의 실행 시간과 플레이북의 전체 실행 시간에 대한 요약을 생성한다.



- 태스크가 시작된 날짜와 시간


- 이전 태스크의 실행 시간(괄호 안에 표시)


- 플레이의 누적 실행 시간



Saturday 22 April 2019  20:05:51 -0700 (0:00:01.465)       0:01:02.732 ********

===============================================================================

install nginx ---------------------------------------------------------- 57.82s

Gathering Facts --------------------------------------------------------- 1.90s

restart nginx ----------------------------------------------------------- 1.47s

copy nginx config file -------------------------------------------------- 0.69s

copy index.html --------------------------------------------------------- 0.44s

enable configuration ---------------------------------------------------- 0.35s



Posted by 김용환 '김용환'

댓글을 달아 주세요


scala에서 json 파싱할 때, 사용할 수 있는 간결한 라이브러리로 ujson이 있다. upickle이 있긴 하지만 아직은 불편하다.


http://www.lihaoyi.com/post/uJsonfastflexibleandintuitiveJSONforScala.html



사용 예시이다.



import ujson.Value


object UjsonSampleMain {

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

    val input =

      "{\n  \"id\": \"c730433b-082c-4984-9d66-855c243266f0\",\n  \"price\": 10,\n \"emptyValue\": \"\",\n \"name\": \"Foo\",\n " +

        " \"counts\": [1, 2, 3],\n  \"values\": {\n    \"bar\": true,\n    \"baz\": 100.001,\n    \"qux\": [\"a\", \"b\"]\n  }\n}"


    // json을 읽는다

    val data: Value.Value = ujson.read(input)


    // 'id' 값을 읽는다

    println(data("id").isNull)

    println(data("id"))

    println


    // type

    println(data("id"))          // Value.Value

    println(data("id").render()) // String


    // 'counts' 값을 읽는다

    println(data("counts"))

    println


    // 'name' 값을 읽은 후 reverse한 값을 기존 json에 저장한다

    data("name") = data("name").str.reverse

    println(data.render())

    println


    // json의 Map 데이터는 obj에서 관리된다

    println(data.obj)

    println


    // json 문자열을 Map으로 확인한다.

    data.obj.foreach(tuple => println(tuple._1 + ":" + tuple._2))

    println


    // json의 values 문자열을 Map으로 확인한다.

    data.obj("values").obj.foreach { case (k, v) => println(k + ":" + v) }

    println


    // json의 values.bar의 값을 boolean으로 읽는다.

    println(data.obj("values").obj("bar").bool)

    println


    // 숫자 값

    println(data("price").num.intValue())


    try {

      // 잘못된 json

      val wrong = "}" + input + "{"

      ujson.read(wrong)

    } catch {

      case _: Throwable => println("wrong json")

    }

  }

  

  

결과



false

"c730433b-082c-4984-9d66-855c243266f0"


"c730433b-082c-4984-9d66-855c243266f0"

"c730433b-082c-4984-9d66-855c243266f0"

[1,2,3]


{"id":"c730433b-082c-4984-9d66-855c243266f0","price":10,"emptyValue":"","name":"ooF","counts":[1,2,3],"values":{"bar":true,"baz":100.001,"qux":["a","b"]}}


Map(id -> "c730433b-082c-4984-9d66-855c243266f0", price -> 10, emptyValue -> "", name -> "ooF", counts -> [1,2,3], values -> {"bar":true,"baz":100.001,"qux":["a","b"]})


id:"c730433b-082c-4984-9d66-855c243266f0"

price:10

emptyValue:""

name:"ooF"

counts:[1,2,3]

values:{"bar":true,"baz":100.001,"qux":["a","b"]}


bar:true

baz:100.001

qux:["a","b"]


true


10

wrong json




Posted by 김용환 '김용환'

댓글을 달아 주세요


https://megalohan.blogspot.com/2017/09/yarn-mrv2.html

 yarn.scheduler.minimum-allocation-vcores : 컨테이너에 할당 할 수 있는 최소 Vcore 개수

  yarn-scheduler.maximum-allocation-vcore : 컨테이너에 할당 할 수 있는 최대 Vcore 개수


https://www.cloudera.com/documentation/enterprise/5-8-x/topics/cdh_ig_yarn_tuning.html

Posted by 김용환 '김용환'

댓글을 달아 주세요