redis 사용에 질문이 있습니다.

백연구원의 이미지

redis 에 빈번한 주기로 데이터를 적재하려고 하는데요,

redis-cli 로 (로컬) 서버에 접속만 해도 TIME_WAIT 상태가 1개 생기는 것을 확인했습니다. 이 상태는 정상적은 tcp 커넥션 과정이니 문제가 없다는 것은 아는데요. 이 주기가 빈번해져도 문제가 없을까요? 가령 아래와 같은 코드가 무한히 돌아가고 있다고 보셔도 됩니다.

while (1) {
    redis connect()
    redid close()
}

대략 돌려보니 TIME_WAIT 상태로 1만개 이상이 유지됩니다. 이상태로 운영해도 문제가 안될까요? 또한 redis-cli info 에서 total_connections_received 의 값은 계속 증가하고 있고요. 이 값은 단순히 연결을 받은 횟수를 모두 기록하기 때문에 상관 없다는 글도 보기는 했습니다)

혹시 이렇게 자주 빈번하게 뭔가를 저장해야 할 때 사용할 수 있는 팁이 있다면 부탁드립니다. (매번 새로운 스크립트 호출이라 connection 을 열고 있을수는 없을 것 같아요. 혹시 세션 정보를 파일에 남겨놓고 재사용하는 것이라면 모를까)

답변에 미리 감사드립니다.

... tcp_tw_reuse, tcp_twrecycle 의 값 변경은 문제 해결에 별로 도움이 되지 않는 듯 합나다.

백연구원의 이미지

redis.conf 에서 unixsocket 을 사용하도록 주석을 풀고 connect('/tmp/sock') 을 사용하면 될 것 같기는 한데 이게 다른 영향은 없으려나 찾아봐야 할 것 같네요. 우선 TIME_WAIT 상태가 증가하지 않는 것은 확인되었습니다만 지식이 짧아 올바른 방향인지 의문입니다. 저 sock 이 atomic 이 보장이 되느냐가 문제 같거든요. 병렬로 실행되는 프로세스에서 이용될 예정이라..


소곤소곤

라스코니의 이미지

프로파일링을 해보셔야 하겠는데요.
먼저 redis connect()와 close()의 비용을 알아야 합니다.

redis connect()
1kb, 10kb, 100kb, 1Mb 데이터 보내기
redid close()

등을 수행하셔서 상대적인 connect(), close() 비용을 대략 파악하시고 만약 1Mb 사이즈를 한번에 보내는 것이 맞다라고 판단이 드신다면

1Mb 버퍼를 2개 만드시고 ping-pong 버퍼로 운영하시면 적절하지 않을까 싶습니다. 보통 connect()나 close()시에 문제가 발생할 확률이 딴 부분보다 높기 때문에 가능한 줄이는게 좋다고 봅니다. 가급적이면 처음에만 connect하고 프로그램 종료시 close하는 것이 불필요한 로드를 줄이는 방법입니다.

백연구원의 이미지

혹시 명쾌한 답을 주신 것인데 제가 지식이 짧아서 이해를 못하고 댓글을 작성하고 있을 수도 있다는 점 감안하고 봐주세요.

우선 현재 구조에서는 연결을 유지하면서 쓸 수 없는 구조인데요, 특정 페이지가 로딩될 때 마다 페이지에서 redis에 connect 해서 아주 작은 단위의 데이터(1kb이하)를 기록 합니다. 이 페이지의 호출 빈도가 문제인데요. 대략 10,000 CPS 정도 예상하고 있습니다. 고로 동작시켜놓고 netstat로 보면 TIME_WAIT 이 우왕 (...)

웹쪽 지식이 전무하다보니 무언가(!)에서 redis에 연결을 해놓고 페이지가 호출될 때 그 connection 을 사용할 수 있도록 하는 방법이 있다면 사용해도 괜찮을 듯 하지만 그게 atomic 하게 동작 되는지는 잘 모르겠습니다. :-(

그래서 생각해낸 내용이 /tmp/redis.sock 을 이용하자는 것이었는데요, 실제로 사용을 해보니 문제가 어느정도 해소되는 듯 보이나 이게 근본적인 해결책인지는 잘 모르겠습니다.

애초에 설계가 잘못되었고 말씀하신대로 연결을 계속 유지할 수 있는 방법을 찾는게 최선일까요?


소곤소곤

라스코니의 이미지

우선 저는 redis에 대해서 전혀 모릅니다만 잠깐 웹을 검색해 보니 자료 구조형(NoSQL)의 일종으로 보이네요.

먼저 1 kb 이하 (정도)의 데이터를 매번 redis에 던져줄 필요가 있나 의심이 드네요. 1kb 를 보내는 것은 정말 찰라의 순간이 소요된다라고 볼수 있죠. 그렇지만 그때마다 connect, close를 한다면 여간한 시스템도 버거울 듯 하고요 CPS가 call per second를 의미하나요? 1초당 1만번 이런 콜이 발생한다면 그에 따라 오버헤드가 엄청 크죠.

만약 1 Mb 버퍼를 둔다면 약 1000개의 call 을 한번에 처리할 수 있게 될 거구요. 그렇다면 초당 한 10번 정도만 보내도 된다는 계산이 나오죠. 아마 redis도 이런 방식을 훨씬 처리를 힘겨워하지 않고 처리할 수 있을 것입니다.

고로 페이지가 로딩될 때마다 보내는 것이 아니라 적당량을 모으고 있다가 (ping pong 버퍼 등) 주기적 또는 업데이트 필요시 redis에 보내도록 하는 것이 좀 더 퍼포먼스 측면에서 유리합니다. 보통때는 아무런 사용에 문제가 없는 API (connect, close 등) 도 부하가 몰리는 특정 조건이 되면 이상하게 안되는 경우가 많거든요.

백연구원의 이미지

우선 별도의 모듈(pong을 처리할 수 있는)을 만드는건 몇 가지 이유로 포기 했었는데요. 전체 플로우를 다시 검토 해봐야 할 듯 하네요.
답변 주셔서 감사합니다. :-)

* connection per second 의 의미로 사용하였습니다.


소곤소곤

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.