저희가 서비스 하려고 하는것은 사용자의 위치값을 실시간으로 서버로 전송하여 DB에…

저희가 서비스 하려고 하는것은 사용자의 위치값을 실시간으로 서버로 전송하여 DB에 저장하고 그것을 기반으로 서비스 하는 구조입니다.

만약 User가 1000명이 있고 1초마다 전송을 해서 DB에 저장을 해야 한다면 하루 86,400,000전송 Query 및 DB Insert및 Update Query가 일어 나야합니다.

DB Read 별로 발생을 하지 않습니다.

Mysql로는 감당이 안될거 같아 aws DynamoDB를 살펴보고 있는데 이것도 비용이 장난이 아니네요 ..

Route53서비스를 받는다고 했을때 Query에 대한 비용도 마찬가지구요..

현제는 Http방식으로 서버에 전송해서 DynamoDB에 저장하는 방식을 생각하고 있는데 Socket방식으로 전송하고 자체서버에 mongoDB등 noSql 로 저장을 하는게 낳을지.. 비용적인 측면에서 말이죠..

Mqtt도 고려를 해보고 있는데 알고 있는 지식이 전무한 상태라 러닝커브가 심하게 발생할거 같기도 하고…

어떤 방식으로 설계를 하는것이 가장 현명한 방법일까요?? 물론 비용적인 측면에서 말이죠…

사용자가 1000명이 아니라 10000명 그보다 많아질때는 비용이 장난아니게 나올거 같아서요… 물론 그만큼 버니까.. 엄청난 부담은 아니겠지만 말이죠…^^(희망사항이겠죠)

15 thoughts on “저희가 서비스 하려고 하는것은 사용자의 위치값을 실시간으로 서버로 전송하여 DB에…

  1. HTTP request로 web server에 위치정보를 보내고, 그 웹 서버에서는 Queue server에 기록하도록 합니다. DynamoDB던 RDBMS던 웹 서버에 바로 붙이면 실시간 처리를 하겠다는 의미가 되고, 장애 발생시 대응 여유가 없게됩니다. Queue 서버를 붙이면 write 지연을 줄일 수 있고, Queue 서버에 들어가있는 데이타를 batch 형식으로 dispatch해서 DynamoDB 같은 곳에 write하면 됩니다. 만약 문제가 생겨도 Queue는 실패한 메세지(데이타)를 그대로 유지하므로 데이타 유실 가능성이 줄어듭니다. 좀 더 확장 가능한 구조로 설계하려면 ELB 아래 메세지 수신을 할 웹 서버들을 두고, 또 다른 ELB 아래 Queue 서버들을 두어서 선형적인 성능확장이 가능하도록하고 DynamoDB나 RDBMS 같은 Persistant storage를 적절히 배치하면 고민하시는 부분이 상당 부분 해결될 겁니다.

  2. 1초마다 전송이라는 설계가 지나치게 이상적이라고 생각합니다. 사람들이 그렇게 자주 움직이지 않고, 상용 GPS가 그렇게 정확한 위치 추적이 되는 것도 아니고요. 주기를 늘리거나, 로컬스토리지에 쌓아서 한번에 업로드하거나 하는 대안을 생각해 봅니다.

  3. 큐서비스를 도입하는것도 하나의방법일것같습니다.
    큐를 통해 db, nosql등의 영구저장소에 일종의 버퍼링을 통해 부하를 덜고 비용도 줄일수잇습니다.

  4. 윗분들이 이야기하신 것처럼 유의미한 데이터 변경이 발생한 시점에만 전송하는 구조가 가능하면 트래픽은 꽤 줄어들 것 같고요. MySQL 대신 Write 성능이 좋아진 Aurora도 검토해보실 수 있을 것 같고, 큐(실시간 전송)를 고려하신다면 가성비 좋은 Ably 같은 서비스도 보시면 도움이 되실 것 같습니다.

    https://www.ably.io/reactor

  5. 앞에 답해주신분들 감사드립니다.

    제가 서비스의 특징을 잘설명을 못했군요…

    제가 서비스를 하려고 하는것이 콜택시 서비스다 보니까..
    기사들의 위치를 실시간으로 전송한후 배차할때 실시간으로 정확한 위치를 기반으로 배차를 해야 합니다. 그래서 배치처를를 한다든가 하는것은 무의미합니다 이미지나간 위치기 때문이죠..

    현재는 5초마다 위치를 전송받고 있는데 그것도 부정확해서 1초마다 전송을 받으려고 합니다

    도시의 경우에는 5초정도도 사치스런 주기인데 지방의 경우에는 순서배차라는것이 존재해서 대기지역에 먼저 들어간사람이 앞순번이 되기 때문에 특히 위치전송이 실시간으로 이루어지는것이 중요하거든요…택시는 계속 움직이고 있죠.. 1초에도 수미터를 달리는 존재라…^^

  6. 궁금한게 있습니다. 콜택시인데 왜 기사 위치정보를 받아야하나요?
    콜 요청이 오면 그 정보를 기사들에게 발송하면 되는 게 아닌가요??

  7. 제가 보기엔 동기방식의 게임서버와 유사한 구조가 맞을듯 합니다 위치데이터의 경우 HTTP 보단 TCP나 UDP로 전송을 하고 DB 대신 메모리에 저장하는 방식으로 하고 서버 간 공유 메모리로 Redis 두거나 아예 다른 방식으로 Virtual Actor(azure fabric, akka 등등) 기반의 솔루션을 적용하는게 좋아 보입니다.

  8. 위치데이터가 쌓인 이후에 어느정도 시간 이후에 사용하셔야 하는건가요?
    완전히 리얼타임이 아니라면, 제가 추천드리는 구조는
    APP – 키네시스 프로듀서 – 키네시스 – 키네시스 컨슈머 – RDMS/Dynamo
    프로듀서는 스케일 아웃이 가능한 구조로 만들고,
    컨슈머는 사용자의 위치값을 적당히 aggr 하여 데이터를 줄이는 방식입니다.
    (앱에서도 비슷한 일을 해주면 더 좋을 것 같구요.)

  9. 초당 1천 쿼리면 그리 많은 건 아닌 것 같습니다. 그냥 MySQL로도 별 문제 없는 분량 같네요. 비용도 그닥 고민할 정도는 아닐 것 같은데요. 과거 데이터를 저장하지 않아도 된다면 스토리지 용량 문제도 별로 없을 거구요. 물론 1만을 넘어가기 시작한다면 좀 골치아파질 수는 있습니다.

    확장성을 더 중시하고, 복잡한 쿼리를 할 필요도 별로 없을 거라는 점을 고려하면 redis도 좋은 선택이 될 겁니다. 심플하기도 하면서 클러스터로 얼마든지 확장할 수 있고, 속도도 빠르죠.

    웹 서버를 거치는 게 좋을지 아닐지는 성능보다 보안 등 다른 이슈가 더 영향을 많이 주는 것 같습니다. 다른 이슈가 없으면 클라이언트에서 바로 redis에 연결하도록 하면 성능 면에서는 가장 효율적일 겁니다.

  10. mysql 로도 크게 문제는 없을 것 같구요, read 이슈가 없다면 aws sqs(저는 별로 추천하진 않습니다만) 같은 큐를 이용해서 시퀀셜하게 데이터가 입력되도록 할 수도 있겠습니다.

    박영록님 말씀대로 redis 를 사용하면 문제가 깔끔하게, 아주 깔끔하게 해결되긴 합니다. redis 는 보통 100k/s 의 퍼포먼스를 내 주니까요. 논리적 샤딩 로직까지 만든다면 redis 노드를 늘리는 만큼 퍼포먼스가 나올 겁니다. 근데 rdbms 같은 자유로운 쿼리는 포기하는게 좋겠죠.

    솔루션은 생각하는 대로 나올것 같습니다.

  11. redis에 두고 일정기간 이상 필요없어진 데이터는 날리는 식으로 운영하는게 이상적일 듯 싶네요. aws를 굳이 도입해야 하는가에 있어서는 다소 회의적이구요.

  12. 제가 올린글이 다른 방향으로 흘러 들어 가는것 같아 그러는데요 ..

    제가 고민하는것은 전송쿼리등 비용적인 부분을 고민하는거였습니다. 그런데 … 방식에 대한 논의가 대부분이네요 .. 그닥 비용적인부분에서 도움은 되지 않지만 , 답글 다신분들의 말씀이 많은 도움이 되었습니다. 현재 2년넘게 태스트 서비스를 잘 수행하고 있는터라 방식에 관해서는 사실 그닥 중요하지 않습니다. AWS로 서비스를 옮기면서 새로운 비용적인 이슈가 생겨서 질문을 드린 부분입니다.

    제가 단순생각했을때 기사가 앱을 켰을때 Websocket으로 연결한후 위치정보를 socket으로 전송을 하면 전송쿼리에 대한 부분은 해결이 될듯도 한데 … 제가 개발태스트후 올려 드리도록 하겠습니다.

    혹 저와 같은 고민을 하고 계시는 분들이 있을거 같아서요..

    Websockt으로 위치정보를 전송한후 socket Server에서 MongoDB로 저장하는 방식을 현재 생각하고 있습니다.

    다들 감사드립니다.

  13. 앞에서 설명하신 것을 참고하면,
    콜한 고객의 위치 정보를 택시 쪽으로 보내서 가까운 위치의 택시가 응답하도록 하면 생각하시는 비용문제가 많이 줄어 들 것 같은데요…
    지나가다 떠오른 생각을 남겨 봅니다. ^^;

  14. 도움이 되실지 모르겠지만, 제가 콜택시 서비스를 개발 및 운영할때 비슷한 문제가 있었습니다.

    그때엔 실시간 택시 배차는 Elasticache의 Redis에서 지원하는 Geo Query와 TTL을 사용하여 해결 했습니다.
    https://redis.io/commands/georadius

    Geo Hash 기술이 GEO SQL의 그것보다 분해능이 떨어지기는 하지만 오차범위가 수m 정도밖에 되지 않으니 사용해보시는걸 추천드립니다. 그리고 데이터 보관은 DB에 하지 않고, 서버 log로 기록하여 S3로 빼서 나중에 Spark등을 돌려서 분석을 했습니다.

    그리고 WebSocket으로 콜택시 서비스 만드는건 추천드리고 싶지 않습니다. 모바일 환경상 워낙 끊어지거나 불안정할 때가 많아서 Polling등으로 서비스 구성하시는게 안전합니다. 저도 한번 해봤다가 안되서 포기했습니다.

Comments are closed.