보통 celery.py와 tasks.py를 두고 worker를 실행시키고

애플리케이션 서버에서는 tasks.py를 import해서 사용한다.


근데, 여기서 사용자의 눈에는 안보이는 것이있다.

워커를 실행할때는 당연히 celery.py를 이용해서 실행하기 때문에 별 이상해 보일것이 없는데,

잡을 줄때는 어떻게 이녀석이 redis에 커넥션이 되서 일을 전달 할 수 있는 것일까?


tasks.py를 보면 우리가 사용한 app은 결국 celery.py에서 가져온 것이기 때문에 일을 주는 애들도 각각 이 celery.py를 실행하여 celery app instance를 만들기 때문에 저런 상황이 가능한 것이다. 즉, 워커들도 각각 celery.py를 실행하듯, 사용하는 쪽에서도 celery.py를 각각 실행해서 app을 가지고 있다는 것!


'celery' 카테고리의 다른 글

[celery] How to run different multiple workers using different queue  (0) 2017.12.05
celery 오해와 진실  (0) 2015.03.13
Revoking task  (0) 2014.11.24
예약 푸시  (0) 2014.11.20
블로그 이미지

시간을 거스르는자

,

http://docs.mongodb.org/manual/administration/monitoring/

프로파일링 하고자하는 DB를 선택해서

db.setProfilingLevel(1)

셋팅을 해주고

db.system.profile.find( { millis : { $gt : 100 } } )

이런식으로 찾으라고 되어있다.

하지만 millis는 그냥 자신의 쿼리가 얼마나 오래 걸린지만 나타낼뿐, 자신이 기다린 db read/write lock time이 얼마나 되며 자신이 수행되는동안 db read/write lock time을 얼마나 잡았는지는 포함되지 않는다.

profile doc 내부에 보면 아래와 같은 lock에 대한 정보가 추가로 있는데

system.profile.lockStats.timeLockedMicros

system.profile.lockStats.timeAcquiringMicros

timeLockedMicros는 자신이 lock을 얼마나 잡았는지, timeAcquiringMicros는 자신이 lock을 잡기위해 기다린 시간을 뜻한다.

따라서 client측에서의 총 기다린 시간은 millis + 자기가 기다린 lock시간이 되겠다. 그리고 자기가 잡은 lock은 그다음 쿼리에 영향을 미칠거고..

만약 자기가 lock을 잡기위해 기다린 시간이 엄청 길다면 앞에 있는 쿼리가 lock을 걸고 기다렸거나 아니면 다른 리소스에서 디스크자원을 써서 기다리는 시간이 길어졌다고 볼수 있다.

보통은 millis로만 검색해서 실제로 lock이 얼마나 있었는지 못보고 지나갈 수도 있는데 이 lock타임으로 검색하거나, 특정 시간때에 몽고디비가 이상 현상이 있었다면 그시간때 ts로 profile doc을 검색해보는 것이 좋을 듯하다.


* 참고로 아마존을 사용할때 EBS Volumes에 Read/Write Bandwidth 그래프를 보고 언제 갑자기 read/write량이 몰렸었는가를 볼 수 있으니 위 내용과 관련해서 같이 보면 좋다. 이런걸 보고 몇 IOPS가 필요한지 판단할 수 있을 듯하고, 그리고 가끔 보면 튀는게 있는데 아마도 클라우드 서비스라 그런지 다른 곳과 총 bandwidth를 나눠쓸거 같다는 생각이 들고 그러다보면 순간적으로 우리쪽에 Disk I/O 기다림이 생길수 있어서 이때 쌓였던 I/O들이 한번에 몰리면서 튀는현상을 만들어 내지 않았나 가정을 해본다.

env:200KDAU500GB1500IOPS

'mongoDB' 카테고리의 다른 글

mongodb "convert to capped collection" effect  (0) 2018.02.23
How to mount mongoDB disk to /data folder  (0) 2018.02.23
mongos setup on centos  (0) 2018.01.12
Shading  (0) 2014.04.23
블로그 이미지

시간을 거스르는자

,

functools.wraps에 대해

python 2015. 4. 15. 16:52

functools.wraps는 보통 python fucntion을 wrapping할 때 원래 function의 정보들을 유지 시키기 위해서 사용된다.

간단한 wrapper 코드를 보자.


import functools


def print_iam_wrapper(method):

    @functools.wraps(method)        ----- 1

    def wrapper(*args, **kwargs):    ----- 2

        print "I'm wrapper"

        return method(*args, **kwargs)


    return wrapper


@print_iam_wrapper

def iam_func():

    print 'iam_func'


print iam_func.__name__                  ----- 3 

iam_func()                                       ----- 4


여기서 1번을 제거해도 4번의 결과는 같다. 하지만 3번의 결과는 다르다.

wraps가 하는 일은 wraps, update_wrapper, partial 코드를 살펴보면 이해가 간다.

(3개의 function에 대한 코드는 아래에 두겠다.)

1번 decorator가 실행될때 method가 넘어가서 넘어오는 것은 결국 wraps의 결과인 partial() 리턴값인데 이것은 newfunc 이다. 그렇다면 1번은 @newfunc가 되었다고 볼 수 있다.


그리고 @newfunc에 파라미터로 넘어가는 것은 아래있는 wrapper function이 된다. 이때 newfunc은 update_wrapper를 실행하고 있으므로 이는 또한 @update_wrapper와 같다. 다만 이때 wrapped로 처음에 전달된 method 즉 iam_func이 넘어가 있을 것이다. 결국 의미는 wrapped에 설정되어있는 '__module__', '__name__', '__doc__', '__dict__' attritbute를 wrapper에 셋팅하여 던져주는 것이다.



* 참고) update_wrapper, wraps, partial

WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')

WRAPPER_UPDATES = ('__dict__',)

def update_wrapper(wrapper,

                   wrapped,

                   assigned = WRAPPER_ASSIGNMENTS,

                   updated = WRAPPER_UPDATES):

    for attr in assigned:

        setattr(wrapper, attr, getattr(wrapped, attr))

    for attr in updated:

        getattr(wrapper, attr).update(getattr(wrapped, attr, {}))

    # Return the wrapper so this can be used as a decorator via partial()

    return wrapper


def wraps(wrapped,

          assigned = WRAPPER_ASSIGNMENTS,

          updated = WRAPPER_UPDATES):


    return partial(update_wrapper, wrapped=wrapped,

                   assigned=assigned, updated=updated) 


def partial(func, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = keywords.copy()
        newkeywords.update(fkeywords)
        return func(*(args + fargs), **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc























'python' 카테고리의 다른 글

gunicorn vs uwsgi  (0) 2017.01.20
flask async response  (0) 2017.01.04
Apple Push Notification Service(APNs) python modules  (0) 2015.04.07
Getting specific timezone timestamp from time string  (0) 2015.01.20
Shallow copy VS Deep copy  (0) 2014.08.27
블로그 이미지

시간을 거스르는자

,