[spark] 셔플 관련 자료

scala 2018. 12. 4. 14:39



spark에는 여러 셔플(shuffle) 함수의 성능적인 부분을 설명한 자료이다.





Everyday I'm Shuffling - Tips for Writing Better Spark Programs, Strata San Jose 2015 from Databricks




책으로 보려면, 아래 책을 참고하깅 바란다. 


Scala and Spark for Big Data Analytics: Explore the concepts of functional programming, data streaming, and machine learning 


https://www.amazon.com/Scala-Spark-Big-Data-Analytics/dp/1785280848


Posted by '김용환'
,





sql console로는 update_date 컬럼에 between..and 를 검색했더니 잘 동작했다.


select hostname, domain from server where update_date BETWEEN '2018-11-28' AND '2018-11-28 23:59:59'



코드에 반영했지만 아래와 같은 에러가 발생했다.


ORA-01843: not a valid month


아래 쿼리로 확인해도 정상적으로 AMERICAN으로 잘 나왔다.



select * from nls_session_parameters where parameter = NLS_DATE_LANGUAGE;





원인은 컬럼에 timestamp 타입인지 명시하지 않아서 발생한 것이다. 


따라서 아래와 같이 TO_TIMESTAMP를 사용하는 방식을 사용하면 정상적으로 작동한다.



select hostname, domain from server where update_date BETWEEN  TO_TIMESTAMP('2018-11-28 00:00:00', 'YYYY-MM-DD HH24:MI:SS') AND TO_TIMESTAMP('2018-11-28 23:59:59', 'YYYY-MM-DD HH24:MI:SS')



Posted by '김용환'
,





스파크는 선형 회귀 알고리즘의 RDD 기반 구현을 제공한다. 

https://spark.apache.org/docs/latest/mllib-linear-methods.html#regression




SGD(stochastic gradient descent)를 사용해 정규화가 필요 없는 선형 회귀 모델을 학습시킬 수 있다. 이는 다음과 같은 최소 제곱 회귀(least squares regression) 공식을 풀 수 있다.


정규화가 없는 선형 회귀 모델은 최소 제곱 회귀 공식을 사용할 수 있다는 뜻인데. 이게 즉, 평균 제곱 오차와 같다는 내용입니다. 


https://thebook.io/006958/part02/ch03/03/



f(가중치) = 1/n ||A 가중치-y||2 (즉, 평균 제곱 오차(MSE, mean squared error)다)




여기서 데이터 행렬은 n개의 로우를 가지며, 입력 RDD는 A의 로우 셋을 보유하고 각각은 해당 오른쪽 레이블 y를 가진다. 





https://github.com/apache/

spark/blob/master/mllib/src/main/scala/org/apache/spark/mllib/regression/LinearRegression.scala를 참조한다.





참고로, 예측값과 타깃값의 차이를 제 곱하여 더한 후에 샘플의 개수로 평균을 내면 평균 제곱 오차입니다.

https://en.wikipedia.org/wiki/Mean_squared_error






Posted by '김용환'
,








org.apache.hadoop.ipc.RemoteException: No lease on /google/public_plus/20181127/23_merged (inode 2683729964): File does not exist. [Lease.  Holder: DFSClient_NONMAPREDUCE_-39928930_1, pending creates: 8]





하둡 소스를 보면, 파일이 없거나 디렉토리이면 위의 에러가 발생한다. lease 이슈는 아니다..




https://github.com/facebookarchive/hadoop-20/blob/master/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java#L3105


private void checkLease(String src, String holder, INode file) 

                                                     throws IOException {


    if (file == null || file.isDirectory()) {

      Lease lease = leaseManager.getLease(holder);

      throw new LeaseExpiredException("No lease on " + src +

                                      " File does not exist. " +

                                      (lease != null ? lease.toString() :

                                       "Holder " + holder + 

                                       " does not have any open files"));

    }




참고로 lease는 write lock과 비슷한 개념이다.


Leases

In HDFS these locks are called Leases. Leases are granted to a client which request to open a file for a write operation (e.g. create / append / truncate a file.) 


https://www.raviprak.com/research/hadoop/leaseManagement.html






사실 생각해보면. 실제로 있어야 하는데 존재했다가 삭제된 것이다. 


이는 병렬 이슈인 것이다.


https://stackoverflow.com/questions/7559880/leaseexpiredexception-no-lease-error-on-hdfs




spark이라면. 다음과 같이 설정을 해서 speculative optimization 알고리즘(병렬)을 끄도록 한다.



sparkConf.set("spark.speculation", "false");

sparkConf.set("spark.hadoop.mapreduce.map.speculative", "false");

sparkConf.set("spark.hadoop.mapreduce.reduce.speculative", "false")



hive라면 다음과 같은 설정을 진행한다. 



set mapreduce.map.speculative=false;

set mapreduce.reduce.speculative=false;

set hive.mapred.reduce.tasks.speculative.execution=false;

Posted by '김용환'
,

Database Class Loader started - derby.database.classpath=''

18/11/29 22:05:54 ERROR PoolWatchThread: Error in trying to obtain a connection. Retrying in 7000ms

java.sql.SQLException: A read-only user or a user in a read-only database is not permitted to disable read-only mode on a connection.

at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)

at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)

at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source)

at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)

at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)

at org.apache.derby.impl.jdbc.EmbedConnection.setReadOnly(Unknown Source)

at com.jolbox.bonecp.ConnectionHandle.setReadOnly(ConnectionHandle.java:1324)

at com.jolbox.bonecp.ConnectionHandle.<init>(ConnectionHandle.java:262)

at com.jolbox.bonecp.PoolWatchThread.fillConnections(PoolWatchThread.java:115)

at com.jolbox.bonecp.PoolWatchThread.run(PoolWatchThread.java:82)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

at java.lang.Thread.run(Thread.java:745)

Caused by: ERROR 25505: A read-only user or a user in a read-only database is not permitted to disable read-only mode on a connection.

at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)

at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)

at org.apache.derby.impl.sql.conn.GenericAuthorizer.setReadOnlyConnection(Unknown Source)

at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.setReadOnly(Unknown Source)




원인은 권한이다. spark-shell의 권한이 root 또는  metastore_db 디렉토리의 권한을 확인한다.

Posted by '김용환'
,



kubernetes에서 cronjob 실행하기 


$ vi cronjob.yaml

apiVersion: batch/v1beta1

kind: CronJob

metadata:

  name: sleepy

spec:

  schedule: "*/1 * * * *"

  jobTemplate:

    spec:

      template:

        spec:

          containers:

          - name: resting

            image: busybox

            command: ["/bin/sleep"]

            args: ["3"]

          restartPolicy: Never





$ kubectl create -f cronjob.yaml

cronjob.batch/sleepy created





시간에 따라 확인한다.



$ kubectl get cronjobs.batch

NAME      SCHEDULE      SUSPEND   ACTIVE    LAST SCHEDULE   AGE

sleepy    */1 * * * *   False     0         <none>          40s



$ kubectl get cronjobs.batch

NAME      SCHEDULE      SUSPEND   ACTIVE    LAST SCHEDULE   AGE

sleepy    */1 * * * *   False     0         1m              2m




Posted by '김용환'
,


kubernetes에서 proxy 사용 예시이다



$ kubectl proxy --api-prefix=/ &

[1] 9789

Starting to serve on 127.0.0.1:8001





$ curl http://127.0.0.1:8001/api/

{

  "kind": "APIVersions",

  "versions": [

    "v1"

  ],

  "serverAddressByClientCIDRs": [

    {

      "clientCIDR": "0.0.0.0/0",

      "serverAddress": "10.1.1.1:6443"

    }

  ]






$ curl http://127.0.0.1:8001/api/v1/namespaces
{
"kind": "NamespaceList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/namespaces",
"resourceVersion": "445783"
"items": [
    {
      "metadata": {
        "name": "default",
        "selfLink": "/api/v1/namespaces/default",
        "uid": "8fd4381e-f15f-11e8-8c69-fa163ec1822d",
        "resourceVersion": "5",
        "creationTimestamp": ",.,,,17Z"
      },
      "spec": {
        "finalizers": [
          "kubernetes"
        ]
      },
      "status": {
        "phase": "Active"
      }
    },
    {
      "metadata": {
        "name": "ingres

...

Posted by '김용환'
,



다음은 kubernetes의 discovery 예시이다.




$ kubectl config view

apiVersion: v1

clusters:

- cluster:

certificate-authority-data: REDACTED

server: https://10.1.1.1:6443

name: kubernetes

...




$ kubectl get secrets

NAME                  TYPE                                  DATA      AGE

default-token-686zl   kubernetes.io/service-account-token   3         3d





$ kubectl describe secret default-token-686zl

Name:         default-token-686zl

Namespace:    default

Labels:       <none>

Annotations:  kubernetes.io/service-account.name=default

              kubernetes.io/service-account.uid=a0b98cf2-f15f-11e8-9449-fa163e9f27a5


Type:  kubernetes.io/service-account-token


Data

====

ca.crt:     1090 bytes

namespace:  7 bytes

token:      xxxx



$ export token=$(kubectl describe secret default-token-686zl |grep ^token |cut -f7 -d ' ')



$ echo $token

xxx



$ curl https://10.1.1.1:6443/apis --header "Authorization: Bearer $token" -k

{

"kind": "APIVersions",

"versions": [

"v1"

],

"serverAddressByClientCIDRs": [

{

"clientCIDR": "0.0.0.0/0",

"serverAddress": "10.1.1.1:6443"

}

]

}

...



이전 결과와 동일하다. 



$ curl https://10.128.0.3:6443/api/v1 --header "Authorization: Bearer $token" -k


{

"kind": "APIVersions",

"versions": [

"v1"

],

"serverAddressByClientCIDRs": [

{

"clientCIDR": "0.0.0.0/0",

"serverAddress": "10.1.1.1:6443"

}

]

}

...




Posted by '김용환'
,



열심히 일했던 카카오의 한 동료가 여의치 않게 퇴사하게 되었다. (1년 조금 안되게 함께 일했던 것 같다.)


하지만 능력있던 그 동료가 소설가로 신인상을 받게 되었다. 


너무 축하해 주고 싶다!!!!!


앞으로 계속 잘 되시기를!!!!


앞으로 책 나오면 잘 볼께요~






http://www.changbi.com/archives/76278?cat=3378


– 제21회 창비신인소설상

사진_장류진_c수상작: 장류진(張琉珍) 「일의 기쁨과 슬픔」

수상자 약력: 1986년생. 연세대 사회학과 졸업, 동국대 대학원 국어국문학과 수료

심사위원: 기준영 김성중(이상 소설가) 박인성 한영인 황정아(이상 문학평론가)

 

선정 이유: 「일의 기쁨과 슬픔」은 짧고 기민하게 잽을 날리는 가벼운 스텝의 복서를 연상케 한다. 회장의 심기를 거스르는 바람에 월급을 전액 카드 포인트로 받게 된 ‘거북이알’이 다시 포인트를 돈으로 전환하기 위해 중고거래에 나선다는 설정은 한숨이 나올 만큼 ‘웃픈’ 이야기지만 재벌총수가의 물의가 연일 보도되는 현실의 거울에 비추어보면 허무맹랑한 소리만은 아니다. 인물들이 나란히 판교 엔씨소프트 사옥 너머로 네모난 하늘을 바라보는 장면에서 보이듯 작품에 묘한 청량감이 있다고 할까. 꽉 짜인 로직을 뚫고 한줄기 바람이 통과하는 듯한, 세상은 만만치 않고 어이없는 일투성이지만 그 안에서 ‘소확행’이든 무엇이든 자기만의 방식으로 적응해나가는 청년세대의 기쁨과 슬픔이 생생하다.




소설 내용은 아래 링크..


https://magazine.changbi.com/q_posts/%EC%9D%BC%EC%9D%98-%EA%B8%B0%EC%81%A8%EA%B3%BC-%EC%8A%AC%ED%94%94/?board_id=2659






Posted by '김용환'
,



namespace에 자원 제한(reousrce limit) 예시



 low-usage-limit name space를 생성한다.


$ kubectl create namespace low-usage-limit

namespace/low-usage-limit created



$ kubectl get namespace

NAME              STATUS    AGE

default           Active    1h

ingress-nginx     Active    1h

kube-public       Active    1h

kube-system       Active    1h

low-usage-limit   Active    19s



자원 제한 정보를 설정한다.



$ vi low-resource-range.yaml


apiVersion: v1

kind: LimitRange

metadata:

  name: low-resource-range

spec:

  limits:

  - default:

      cpu: 1

      memory: 500Mi

    defaultRequest:

      cpu: 0.5

      memory: 100Mi

    type: Container





아래와 같이 진행하면 실행되지 않는다.


$ kubectl create -f low-resource-range.yaml --namespace=low-usage-limit



$ kubectl get LimitRange --all-namespaces

NAMESPACE         NAME                 AGE

low-usage-limit   low-resource-range   1m



$ kubectl get LimitRange




namespace이름을 넣어주고 새로운 deployment를 생성한다. 


$ kubectl create deployment limited-hog --image vish/stress -n low-usage-limit




참고로 삭제할 때도 namespace를 줘야 삭제된다. 


$ kubectl delete deployment limited-hog -n low-usage-limit

deployment.extensions "limited-hog" deleted


$ kubectl delete deployment limited-hog

Error from server (NotFound): deployments.extensions "limited-hog" not found




제대로 실행되었다면. low-usage-limit   limited-hog  의 available이 0이 되지 않을 것이다. (마침 1이다.)


$ kubectl get deployments --all-namespaces

NAMESPACE         NAME                   DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE

default           hog                    1         1         1            1           15m

kube-system       kube-dns               2         2         2            2           1h

kube-system       kubedns-autoscaler     1         1         1            1           1h

kube-system       kubernetes-dashboard   1         1         1            1           1h

kube-system       tiller-deploy          1         1         1            1           1h

low-usage-limit   limited-hog            1         1         1            1           37s



제대로 실행 중이다. 만약 deployment가 잘못 되었다면 STATUS에 잘 표시될 것이다 .


$ kubectl -n low-usage-limit get pods

NAME                           READY     STATUS    RESTARTS   AGE

limited-hog-757fc847ff-mvm7s   1/1       Running   0          1m




pod 설정을 yaml로 보면 제대로 되어 있다. 


$ kubectl -n low-usage-limit get pod limited-hog-757fc847ff-mvm7s -o yaml





 resources:

      limits:

        cpu: "1"

        memory: 500Mi

      requests:

        cpu: 500m

        memory: 100Mi




deployment를 수정해 namespace를 적용한다.


$ kubectl get deployment hog --export -o yaml > new-hog.yaml



namespace: low-usage-limit를 추가하고 deploy한다.


$ vi new-hog.yaml


  labels:

    app: hog

  name: hog

  namespace: low-usage-limit



$ kubectl create -f new-hog.yaml



$ get deployments --all-namespaces

NAMESPACE         NAME                   DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE

default           hog                    1         1         1            1           23m

kube-system       kube-dns               2         2         2            2           1h

kube-system       kubedns-autoscaler     1         1         1            1           1h

kube-system       kubernetes-dashboard   1         1         1            1           1h

kube-system       tiller-deploy          1         1         1            1           1h

low-usage-limit   hog                    1         1         1            1           40s

low-usage-limit   limited-hog            1         1         1            1           8m




work장비에 들어가서 보면 메모리를 12% 쓰고 있다. 


  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND

30062 root      20   0  960872 954176   3120 S 101.0 11.7  26:52.72 stress

 1126 root      20   0  960104 954108   3180 S 100.3 11.7   3:53.52 stress





정리한다.


$ kubectl -n low-usage-limit delete deployment hog

deployment.extensions "hog" deleted

$ kubectl delete deployment hog

deployment.extensions "hog" deleted







출처 : linux foundation kubernetes 예시







Posted by '김용환'
,