사실, 언제부터인가 Python을 쓰다보니,,

그래도 가장 편했던 언어는 JAVA 언어였는데, 요즘 너무 어렵네요 


여러여러 관점에서 다른 원격지에서 생성되는(로그든 어떤거든) 데이터를 수집하기 위해서 API를 서버가 필요한 상황이였습니다(저 같은경우는 사용자 브라우저에서 생성된 로그 데이터의 경우 입니다.)


일단 제가 사용하는 조합은 


Python 2.7에서(Pyenv 로 3으로 올려서 사용했는데, 중간에 소스가 꼬여버리는 바람에) + Flask + Guicorn + Supervisor.d를 이렇게 사용하고 있습니다.


주변 케이스를 찾아보면 현 해당 케이스에서는  Node.js 를 기반으로 긍정적으로 평가하는것 같지만, 굳이 이걸 사용하는건 Python 이 편하기 때문에


먼저 SSL 키를 확보합니다.(확보되어 있다고 가정하고, 구입 또는 letsencrypt를 통해 무료로 발급받았다고 가정) 



먼저 필요한 패키지(?) 모듈들은 이거고 설치는 pip를 통해서 했습니다.

from flask import Flask, request, Response
from flask_cors import CORS, cross_origin
from OpenSSL import SSL


Flask 는 다음과 같이 사용합니다.

app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "*"}})


여기서  CORS를 한이유는 , 저 같은경우 데이터가 브라우저들을 통해서 넘어오는 상황이여서 크로싱 브라우징 이슈를 해결하기 위해 사용하였습니다 


context = SSL.Context(SSL.SSLv3_METHOD)
cert = 'cert.pem'
pkey = 'privkey.pem'
context.use_privatekey_file(pkey)
context.use_certificate_file(cert)


그다음 HTTPS 사용하기 위해서 다음과 같이 하였습니다. 만약 이옵션을 제거하면 HTTP REST API 가 됩니다 


if __name__ == "__main__":
app.run(host='0.0.0.0', port='58080', ssl_context=(cert, pkey))

 

app.run 을 할때 ssl_context를 넣어주면 https로 작동하게 됩니다. 



@app.route("/", methods=['POST'])
@cross_origin()
def api(): data = str(request.get_data())

resp = Response(data)
resp.headers['Access-Control-Allow-Credentials'] = 'true'
return resp

request.get_data()와 같은 형태로 해당 api 주소의 /을 post로 넘겨온 데이터를 받습니다 이제 여기서 저 같은경우에 데이터를 좀더 수정하고 시간을 붙여서 다른 장소로 다시 넘깁니다


그리고 resp부분은 받은 내용에 대해서 그대로 다시 리턴합니다... 데이터를 보내오는 쪽에서 그렇게 해달라고 하더군요. 

사실 웹쪽을 잘모르는데, 제가 다시 보낸다고 해도, header를 저런식으로 안붙여주면 다른쪽에서 받지를 못하더군요.. 


사실 잡설이긴하지만,,, 저 같은 경우는 HDP 플랫폼으로 하둡 데이터를 처리하였는데, Cloudera CDH 쪽 하는 친구의 말을 들어보면 supervisor.d 가 데몬을 키고 끄고 이런 소리를 하길래 superviosr.d 가 클라우데라쪽의 어떤 프로젝트 인줄 알았습니다. 


제대로 이해한거면 supervisor.d는 파이썬의 프로젝트인것 같더군요 (http://supervisord.org/Supervisor is a client/server system that allows its users to monitor and control a number of processes on UNIX-like operating systems.)


보통의 경우 Flask 를 단독으로 띄워서 사용하지는 않는다고 하는것 같습니다. 사실 이번엔 제가 이건 처음이여서 다른것을 참고 하다보니요 아직 wsgi 의 개념은 잘이해는 안가는데 flask+guicorn 조합으로 사용하는것 같습니다.( http://flask.pocoo.org/docs/0.12/deploying/wsgi-standalone/)


그다음 supervisor.d 에는 다음과 같이 적용을 시켰습니다 


[program:api]

command = gunicorn -w5 --certfile=cert.pem --keyfile=privkey.pem api:app -b 0.0.0.0:58080 --pythonpath /root/api

;directory = /root/api

user = root

numprocs=1

autostart=true

autorestart=true



일단 이걸로 사용하다가 ,  다음에는 이걸 사용하다가 Node.js 로 해봐야겠네요.. 


Node.js가 그렇게 좋다는데....(멍)

저작자 표시 비영리 변경 금지
신고

오늘 심각한 고민을 했습니다  ... 자바는 그냥 갔다 버려야되나..


Parallel Python 이거 써보고 할말을 잃었습니다. 생각보다 너무 쉽고.


Parallel Python을 사용하기 위해서는 대략 다음 절차를 수행하시면 됩니다.



연산을 하려는 노드, Master노드에 Parallel Python 설치(http://www.parallelpython.com/) [현재 저같은경우 Python 2.7을 사용하고 있습니다.]


그다음 연산하려는 모든 노드에서 네트웍 대역이 같다면, ppserver.py -a (이 의미는 실제 코드 설명할때 설명0


그리고 마스터 노드에서 병렬처리할 코드를 작업하시면 됩니다.


큰틀은 다음과 같습니다. 


가장 중요한 부분은 ppserver= ppservers=("*",) 입니다. 앞에서 ppserver.py -a  한이유와 같은데, 만약 같은 네트워크 대역폭에 있으면 알아서 감지합니다. 


 job_server.submit(mysum,(100,),callback=sum.result) 


실행할 함수?, 그리고 Parameter, 콜백 함수 입니다. 


만약 이럴경우, 병렬로 돌릴때 그 모듈이 돌아가기 위해 필요한 모듈이 있다고 가정할대, 예를들명 mysum을 연산할때 파이선의 math 모듈이 반드시 필요하다 그럴경우에는 modules = ("math","sys")와 같이 파라메터를 넣어주시면 됩니다.


파이썬이 이렇게 강력할줄이야.. 




import sys,thread
import pp
class myTest:
def __init__(self):
self.value=0
self.lock = thread.allocate_lock()

def result(self, value):
self.lock.acquire()
self.value += value
self.lock.release()


def mysum(n):
result=0
for i in range(1,1000):
result+=i
return result



sum = myTest()

ppserver= ppservers=("*",)

job_server = pp.Server(ppservers=ppservers)
job1 = job_server.submit(mysum,(100,),callback=sum.result)

job_server.print_stats()

job_server.wait()

print "result is "+str(sum.value)

job_server.print_stats()


저작자 표시 비영리 변경 금지
신고
  1. Favicon of http://navisphere.net BlogIcon 룬룬 2016.01.03 15:19 신고

    오늘은 드디어 아는 뭔가가 나와서 반가운 마음이 드네요.
    먼저 복 많이 받으시고요. :) 늘 은은히 이어가는 인연이 즐겁습니다.

    저는 전공이 컴퓨터비전, 패턴인식, 머신러닝에 가까운 사람입니다.
    파이썬도 많이들 쓰더라구요. 아마 MATLAB이 유료이기에 그 대안으로 사용되는 분위기가 아니었나 싶습니다.

    저 또한 처음에는 고가의 MATLAB에서 벗어나보고자 배우기 시작한 것이 Python이고 말씀하신 부분, 그 명쾌하게 한줄로 해결되는 듯한 그 부분에 인상이 깊은 언어로 남아있습니다. 배우기 쉽고 수천의 이미 준비된 라이브러리들.. 그렇지 않을 수가 없었죠. :)

    병렬처리라고 하면 제 머릿속에서는 GPU를 이용한 것들이 먼저 떠오르는데 써주신 Parallel Python은 MPI 같은 환경을 말하는 것인가봅니다.
    어쨌든 Python의 편리함은 부정할 수 없는 것 같고요.

    개인적으로 조금 배우고 써보면서 느낀 점을 단 점 위주로 말씀드려보고자 합니다. 사용하실 때 감안을 해보면 좋을 것 같습니다.
    분야 때문에 환경이 좀 다를 수도 있을 것 같기도 해요.

    1. 빠른 결과를 보기 위한 실험용으로는 최적입니다.
    말씀드렸듯 이미 준비된 모듈들이 너무나도 많습니다. 단순 wrapper들도 많고요.

    2. 짜임새 있는 구조로 아름다운 코드를 만들기는 힘든 것 같습니다.
    제가 실력이 모자라 그런 느낌을 받았을 수도 있는데, 스크립트 언어 특성상 그 부분에 이르러서야 오류가 나기 때문에 아까운 시간들을 놓칠 때가 많습니다.
    단순 문법이나 사용상 오류들을 잡는데 시간을 많이 보냈던 것 같습니다. C/C++에서는 빌드조차 안될 것 같은 그런 오류들 말이에요.
    모듈간 연동시에도 크게 검사 과정이 없기 때문에 코드의 크기가 커질 수록 다루기가 힘든 물건이 되어버리는 것 같습니다.

    3. Type 문제
    제게는 이것이 가장 큰 문제로 다가왔습니다.
    사용하다보면 Numpy 등에서 새로 정의된 Type들을 사용하게 되는데, 이것과 기존 Type 혹은 다른 모듈의 Type들이 혼용되기 시작하면 사람이 이를 다루지 못하는 시기가 오게 됩니다.
    C/C++에서는 강력한 Type 검사를 통해 막아주고 있는 부분인데요, MATLAB등은 Matrix, Cell, Dictionary 정도로 제한이 되고 있는 부분이고요.


    아마 지금은 첫줄 같은 고민을 하시긴 해도, 결국 Java를 선택하는 날이 오시리라 믿습니다.


    그럼에도 매력적인 언어임에는 틀림이 없는 것 같습니다.
    어차피 도구니까요. 적절한 목적에 잘 사용하면 되겠죠. :D

    어제 동생과 이야기하다가 나온 것인데,
    Perl 같은 스크립트가 커지면 Python정도로 확장했다가 더 큰 규모가 필요해지면 기존 언어로 가는게 적절한 순서가 아닐까 싶네요.


    오늘은 살짝 넘어서 이야기한 것 같나요? 아는게 나오니 신이 나서... 넓은 마음으로 봐주시고요. :)
    휴일에도 공부하시는 모습에 박수를 보냅니다. 짝짝짝.


    • Favicon of http://redeyesofangel.tistory.com BlogIcon Yuika eizt 2016.01.03 15:43 신고

      새해 복 많이 받으세요 :)

      생각해보면 가벼운 MPI 같은 느김이 맞을것 같습니다. 저 같은 경우는 MPI같은 것과는 거리가 멀고(아마..) (대강들어본적은 있습니다... 학교 다닐대 배울기회가 있었지만,, 수업이 빡세다고해서.. 선택을 안했지만요..)

      요즘에는 학교에서 나와서 빅데이터를 처리하는데 사용하는 Hadoop(MapReduce,Hbase, Hive ...) 안에 있는것들과 Storm 이런 위주로 사용하고 있네요..

      그러다 보니, 가끔식 어떤 데이터들을 처리할대 한개 컴퓨터에서 돌릴때 약간쫌 꼼수로 MapReduce로 나누어서 돌리거나 그러는데... 약간 사이비이네요. 너무 불편했는데,, 어제 파이선이 보이는것입니다..

      사실 어제는 신기했는데,, 전 이걸 그대로 쓰려는게 아니라 제가 하고 싶은 작업에 응용을 해보고 싶은데.. 별로 재밌게 진행되지는 않는것 같네요..

      어디선가 잘 안돌아가는것 같은데..사실 중간중간 검증하면서 하고 든요.. 에러를 내보내는 상황도 아니라서 약간은 애매하네요

      편리하지만 말씀해주신 것들은 염두해 두고 ,, 사용해 봐야겠네요 ㅎㅎ

      감사합니다. :)

잠깐동안 예제를 따라해보면서 해본 느낌은.. 


잘 모르겠지만 엄청 간단합니다. 


먼저 Parallel Python에서 http://www.parallelpython.com/content/view/18/32/ 에서 다운 받아서, pp를 다운받아서, 돌아갈 머신과 마스터 노드에 python setup.py install 하면 끝..


그리고 사용방법은 계산노드(slave)에서 ppserver.py -a(auto discovery) 하면 끝.. 물론 포트를 지정해 준다면 -p 옵션을 사용하면됩니다. 


그런다음 마스터 노드에서 다음과 같은 방법으로 하면됩니다.  (지금 같은경우는 1master node, 1slave node로 구성된 케이스)



import sys,thread
import pp
class myTest:
def __init__(self):
self.value=0
self.lock = thread.allocate_lock()

def result(self, value):
self.lock.acquire()
self.value += value
self.lock.release()


def mysum(n):
result=0
for i in range(1,1000):
result+=i
return result



sum = myTest()

ppserver= ppservers=("*",)

job_server = pp.Server(ppservers=ppservers)
job1 = job_server.submit(mysum,(100,),callback=sum.result)

job_server.print_stats()

job_server.wait()

print "result is "+str(sum.value)

job_server.print_stats()

#ppservers = ("10.0.0.1",)


slave서버를 입력 하는 방법인데 ppserver("*",) 이 방법은 Master노드와 같은 대역에 있을대 저렇게 하면, 자동으로 인식이됨 저 코드의 경우 1master node에서 1 slave노드에게 계산하라고 해서 callback 한 결과를 보여주고 있습니다. 


Job execution statistics:

 job count | % of all jobs | job time sum | time per job | job server

         1 |        100.00 |       0.0000 |     0.000000 | local

Time elapsed since server creation 0.00300002098083

1 active tasks, 8 cores


result is 499500

Job execution statistics:

 job count | % of all jobs | job time sum | time per job | job server

         1 |        100.00 |       0.0010 |     0.001000 | local

Time elapsed since server creation 0.00399994850159

0 active tasks, 8 cores



몇가지 궁금한게 생겼는데,, 결국에는 RabiitMq같은 Queue는 필요없을것 같은데,, 다중 노드는 어떻게 명령을 내려야되는거며, 어떻게 중간에 합치는게 따로 있나.  그리고 어짜피 쓰레드는 길(GIL)이 걸릴테니, 멀티프로세싱으로 하고 싶은데,, 이것도 되려나.. (답은 간단하더군요)

결론은 파이썬 신기합니다. . 

추가:: 방금전에 해본결과로는 결국에는 작동하는 로컬밖에 나오지 않았습니다. 
사실 몇가지 실험을 해보았는데, 결론은 다음과 같았다  이번에는 모든 10노드를 전부 기동시키고 
연산작업을... 한 1000개를 걸어보았습니다. 

Job execution statistics:
 job count | % of all jobs | job time sum | time per job | job server
        26 |         16.15 |      28.5401 |     1.097695 | 192.168.1.203:60000
        28 |         17.39 |      26.5884 |     0.949585 | 192.168.1.206:60000
         8 |          4.97 |       5.8869 |     0.735865 | 192.168.1.204:60000
         8 |          4.97 |       4.0038 |     0.500477 | 192.168.1.100:60000
         6 |          3.73 |       4.7484 |     0.791398 | 192.168.1.201:60000
        13 |          8.07 |      13.5061 |     1.038933 | 192.168.1.207:60000
        10 |          6.21 |      10.0583 |     1.005829 | 192.168.1.209:60000
        26 |         16.15 |      77.0360 |     2.962923 | local
        36 |         22.36 |      35.4551 |     0.984865 | 192.168.1.208:60000


결과는 다음과 같은데 10노드가 전부 활동하지는 않습니다... 예상에는 알아서 스케쥴링을 하거나, 현재의 상황을 찍었을때 찰나에는 다른 노드에서 일을하지 않고 있거나 그런것 같습니다. 

이 결과를 찾기 위해 이짓 저짓을 많이 해봤는데, 

어쩌면 이 당연한 사실을 찾기위해 몇시간을 순간 날렸네요.

결국은 파이썬이 신기하네요. 하지만 전 그래도 Java가 좋아요,,

스칼라도 공부해야되는데..





저작자 표시 비영리 변경 금지
신고

몇가지 처리해야할 작업이 있습니다. 


몇 가지 케이스에 대해 계속 테스트를 해보고 있지만. 이걸 Hadoop MapReduce로 처리하는것은 정말 성능이 안나오더군요. 흔히 말한는 반복적인 작업... 이걸 Storm, 또는 Spark를 통해 해결해 보고 싶지만. 현재 사정상 신규아키텍처를 도입하는데 문제가 있어서... 


물론,,, 현재 환경은 HDP(Hortonworks Data Platform)2.3 이기 때문에, 설치하거나 실행하는데, 문제는 아닙니다. Storm 같은경우 Topology를 만들면 되겠지만.. 약간 제가 생각하는 작업에는 불리할것 같고.. Spark쪽은 아직 제가 지식이 부족해서 시간대비 성과가 부족할것 같은 생각 때문입니다.


물론, 전 아직까지는 언어중에 Java가 좋지만, 요즘 왠만한 귀찮은 작업들은 Python으로 하고 있었는데(사실 과거에는 Perl도 배워보고 싶엇지만..) 너무 강력해서 계속 쓰게 되네요. 솔찍히 Java로 10줄 만들걸 파이선으로 3줄이면 표현이 되거든요..


사실 이렇게 하다가 고민이 생겼습니다. 다중 노드(현재 저 같은 경우는 10노드 + 추가 2노드) Produce Consumer 패턴?으로 로 작업을 병렬로 처리해보고 싶었는데, 이걸 프로그램으로 하나하나 만들기도 모하고,, 이러저런 고민이 많았는데,,


파이선이 해결해 주었네요 http://www.parallelpython.com/ 몇가지 고민은 Master Node에서 Slave 노드로 작업을 어떻게 넘겨주느냐 여부인데,, 자체적인 Queue가 있는것인지, 아님 외부 Queue를 이용해야하는지 봐봐야겠네요..


지금 RabbitMQ와 Kafaka를 동시에 보고 있는데,,, 제가 제대로 알고 있다면 Kafakfa는 Consumer에게 전달된 메세지가 어떤것인지에 대한 보장??꼭 UDP같은 성격이라... 의 문제가 있어서... 텍스트들을 보다 보면,, 케이스에 따라서는 RabbitMQ를 추천하시더군요 


일단은 이번포스팅의 목적은 파이선에서 병렬 처리를 쉽게 해주는 방법이 있는데,, 그것은 parallel python 입니다.


파이썬 짱짱,, 

저작자 표시 비영리 변경 금지
신고
INFO [alembic.migration] Running upgrade e197124d4b9 -> 1fcfc149aca4, Add a unique constraint on (agent_type, host) columns to prevent a race condition when an agent entry is 'upserted'.

./unstack.sh
cd /opt/stack/neutron/neutron

./git fetch https://review.openstack.org/openstack/neutron refs/changes/77/61677/1 && git format-patch -1 --stdout FETCH_HEAD

~/devstack/
./stack.sh

references




저작자 표시 비영리 변경 금지
신고
얼마후에 해야할것중 하나중; 파이썬이라는것도 생겼군요; 젠장 내일이 복귀지만;

그것보다, 파이썬 요거 참 신기한 녀석입니다..

놀라웠던것이 다른과정도 없이 1+1 했더니 바로 2를 나타나겠했다는;


방금전 http://turing.cafe24.com/을 통해서, 파이썬을 보고 있었습니다.;
print '직각삼각형 그리기\n'

d = float(raw_input('변의 길이 : '))

for i in range(d+1):

    print '* ' * i

area = float((d ** 2) / 2)

print '넓이 : ', area

raw_input()

이걸 돌리려고 했더니,;
File "source/test.py", line1                                                                               
SyntaxError : Non-ASCII character '\Xc1' in file source/test.py on line 1, but no  
 encoding declard; see http://www.python.org/peps/pep-0263.html for the details

이런식으로 계속나오더라고요; 검색도 해보고 그랬더니,, 결론은 여기에 한글이 들어있어서 그렇다고 하네요;;


# -*- coding: cp949 -*-

이걸 붙이면 된다고 하더라고요;; 그런데 계속 안되는 겁니다..;;

이것참 생각해보니 # 이걸 빼먹고;; 드디어 실행..



source/test.py:8,, 넌 또모니..휴

파이썬 왠지 재미있어 보이는데,,;; 이것도 갈길이 너무 멀어요;; 후.

이걸로, 첫번째 실험 끝.;


저작자 표시 비영리
신고
  1. Favicon of http://freethesky.pe.kr BlogIcon Scaldi 2009.01.27 18:26 신고

    저도 파이썬을 공부할려고 하지만 역시 갈길이 먼...

    • Favicon of http://redeyesofangel.tistory.com BlogIcon Yuika eizt 2009.01.27 20:10 신고

      ...!!
      왠지 모르지만, 파이썬 이거 신기한것 같아요!!,

      Hello World?...............

  2. Favicon of http://dejavus.tistory.com BlogIcon dejavus 2009.01.28 10:16 신고

    8번째 줄에 range(d+1)에서 range가 integer를 받아야 한다는 warning이네요
    파이썬은 라이브러리들이 참 잘되있어서
    쫌만 배우면 편하게 코딩 할 수 있다네요 ㅡㅡa

    • Favicon of http://redeyesofangel.tistory.com BlogIcon Yuika eizt 2009.02.01 12:59 신고

      ,,,!!! 몇일후에 나가면 바로 해봐야 될것 같아요, 잠깐 맛만 봐본거지만. 이거 왠지 은근히 재미있을것 같다는...

1

+ Recent posts