<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Parallel Precess on</title><link>https://taetaetae.github.io/tags/parallel-precess/</link><description>Recent content in Parallel Precess on</description><generator>Hugo</generator><language>en</language><lastBuildDate>Wed, 02 Jan 2019 12:43:44 +0000</lastBuildDate><atom:link href="https://taetaetae.github.io/tags/parallel-precess/index.xml" rel="self" type="application/rss+xml"/><item><title>천만 명의 사용자에게 1분 내로 알림 보내기 (병렬프로세스의 최적화)</title><link>https://taetaetae.github.io/2019/01/02/faster-parallel-processes/</link><pubDate>Wed, 02 Jan 2019 12:43:44 +0000</pubDate><guid>https://taetaetae.github.io/2019/01/02/faster-parallel-processes/</guid><description>&lt;p>만약 1번부터 10번까지 번호표가 있는 사람들 총 열명에게 혼자서 동일한 내용의 메일을 보낸다고 가정해보자. 그리고 메일 발송시 한번에 한명에게만 보내야 하는 제한사항이 있을때 과연 당신은 어떤식으로 보내겠는가? 이어서 읽지말고 한번 생각해보자.&lt;!-- more -->
아무것도 고려하지 않고 단순하게 생각한다면 1번 보내고 &amp;gt; 2번 보내고 &amp;hellip; 9번 보내고 &amp;gt; 10번 보내는 방법이 먼저 떠오르게 된다. (for loop 1 to 10 &amp;hellip; ) 하지만 보내야 할 사람들이 많아져서 백명, 천명 많게는 천만명에게 보내야 할 경우 방금과 같은 순차적인 방법을 사용하면 너무 늦게 발송된다는건 코드를 작성하지 않아도 알 수있는 문제&amp;hellip; 그렇다면 어떤 방법으로 보내야 보다 빨리 보낼수 있을까?
이번 포스팅에서는 필자가 운영하고 있는 서비스에서 기존에 있던 병렬프로세스를 어떤식으로 최적화 했는지, 그래서 결국 얼마나 빨라졌는지에 대한 과정을 정리해 보고자 한다. 비단 메일 발송이나 앱 푸시 등 특정 도메인에 국한되지는 않고 전반적인 프로세스에 대해 이해를 한다면 다른 곳에서도 비슷한 방법으로 활용할 수 있을꺼라 기대 해본다.&lt;/p>
&lt;hr>
&lt;h2 id="상황파악-및-목표">상황파악 및 목표&lt;/h2>
&lt;p>(원할한 이해를 돕기 위하여) 먼저 필자가 운영하고있는 서비스를 간략히 소개부터 해야겠다. (그렇다고 필자 혼자 다 하는건 아님^^;&amp;hellip;)
셀럽의 방송이 시작되면 구독한 사용자에게 각 모바일 기기에 설치되어있는 앱으로 알림을 보내어 예정에 없던 깜짝 라이브 방송이나 VOD 영상 오픈을 보다 빠르게 확인할 수 있도록 제공하고 있다.
여기서, 알림이 늦게 발송되면 셀럽은 방송을 시작하고 팬들이 들어오기까지 기다려야 한다거나 반대로 팬들은 방송 시작하고 뒤늦게 방송을 보게되는 불편함이 생기게 된다. 그리고 중복으로 알림이 발송되거나 특정 사용자들에게 발송이 누락되면 안 되는 등 &amp;ldquo;알림&amp;rdquo; 이란 기능은 서비스에 있어서 중요한 기능 중에 하나라고 할수 있다.&lt;/p>
&lt;blockquote>
&lt;p>여기서 &amp;ldquo;발송 시간&amp;quot;은 처음 발송작업 시작부터 마지막 사용자에 대해 사내 발송 플랫폼으로 발송 요청을 하기까지의 시간을 의미&lt;/p>&lt;/blockquote>
&lt;p>그리고 &amp;ldquo;채널&amp;rdquo; 이라는 샐럽단위의 그룹이 있는데 영상과 채널의 관계는 1:N이다. 즉, 하나의 영상을 여러 채널에 연결시킬수 있어서 하나의 영상에 대해 여러 채널들에게 연결을 시켜놓으면 채널을 구독하고있는 각각의 사용자에게 모두 알림을 발송 할수가 있게 된다.&lt;/p>
&lt;p>우선, 알람이 사용자에게 전달되기까지의 큰 흐름은 다음과 같다.&lt;/p>
&lt;figure>&lt;a class="lightgallery" href="https://taetaetae.github.io/images/faster-parallel-processes/push_process.jpg" title="/images/faster-parallel-processes/push_process.jpg" data-thumbnail="/images/faster-parallel-processes/push_process.jpg" data-sub-html="&lt;h2>알림 프로세스&lt;/h2>">
 &lt;img
 class="lazyload"
 src="https://taetaetae.github.io/svg/loading.min.svg"
 data-src="https://taetaetae.github.io/images/faster-parallel-processes/push_process.jpg"
 data-srcset="https://taetaetae.github.io/images/faster-parallel-processes/push_process.jpg, https://taetaetae.github.io/images/faster-parallel-processes/push_process.jpg 1.5x, https://taetaetae.github.io/images/faster-parallel-processes/push_process.jpg 2x"
 data-sizes="auto"
 alt="/images/faster-parallel-processes/push_process.jpg" />
 &lt;/a>&lt;figcaption class="image-caption">알림 프로세스&lt;/figcaption>
 &lt;/figure>
&lt;ol>
&lt;li>서비스에서 보낼 대상과 보낼 정보를 조합하여&lt;/li>
&lt;li>사내 푸시 발송 플랫폼인 사내 발송 플랫폼에게 전달을 하면 플랫폼에 따라 발송이 되고&lt;/li>
&lt;li>최종적으로는 사용자의 모바일 기기에 노출이 됨&lt;/li>
&lt;/ol>
&lt;p>간단하게 &amp;ldquo;병렬로 발송하면 되지 않을까?&amp;ldquo;라는 필자의 생각이 부끄러워질 정도로 이미 redis, rabbitMQ 를 활용해서 아래 그림처럼 병렬 프로세스로 구성되어 있었다.&lt;/p>
&lt;figure>&lt;a class="lightgallery" href="https://taetaetae.github.io/images/faster-parallel-processes/legacy_structure.jpg" title="/images/faster-parallel-processes/legacy_structure.jpg" data-thumbnail="/images/faster-parallel-processes/legacy_structure.jpg" data-sub-html="&lt;h2>기존 구조&lt;/h2>">
 &lt;img
 class="lazyload"
 src="https://taetaetae.github.io/svg/loading.min.svg"
 data-src="https://taetaetae.github.io/images/faster-parallel-processes/legacy_structure.jpg"
 data-srcset="https://taetaetae.github.io/images/faster-parallel-processes/legacy_structure.jpg, https://taetaetae.github.io/images/faster-parallel-processes/legacy_structure.jpg 1.5x, https://taetaetae.github.io/images/faster-parallel-processes/legacy_structure.jpg 2x"
 data-sizes="auto"
 alt="/images/faster-parallel-processes/legacy_structure.jpg" />
 &lt;/a>&lt;figcaption class="image-caption">기존 구조&lt;/figcaption>
 &lt;/figure>
&lt;ol>
&lt;li>라이브가 시작되거나 VOD가 오픈될 경우 api가 호출이 되고 다시 배치 서버에게 영상의 고유번호를 전달&lt;/li>
&lt;li>전달받은 영상의 고유번호를 rabbitMQ의 수신자 조회 Queue에 produce&lt;/li>
&lt;li>수신자 조회 Queue의 consumer인 수신자 조회 모듈에서 영상의 고유번호를 consume 후 아래 작업을 진행
3-1. 영상:채널 은 1:N 구조이기 때문에 여러 채널의 사용자들에게 알림을 발송할 수 있고, 영상에 연결된 채널들의 user를 db에서 가져온다.
3-2. 가져온 user를 (중복으로 알림이 발송되지 않기 위해) java set에 담고 모든 채널을 조회했다면 redis에 sorted set으로 담는다.
3-3. 적당한 크기로 분할하고 이 분할정보를 발송 Queue에 produce&lt;/li>
&lt;li>발송 모듈에서 분할 정보를 consume 하고 아래 작업을 진행 (병렬처리)
4-1. redis 에서 user 모음을 가져오고
4-2. 조회한 user에 해당하는 deviceId를 db에서 가져옴&lt;/li>
&lt;li>deviceId와 컨텐츠 정보를 활용하여 적절한 payload를 구성 후 사내 발송 플랫폼 에게 전달&lt;/li>
&lt;/ol>
&lt;p>기존 구조에서 발송 시간은 서비스에서 구독자 수가 가장 많은 채널 기준으로 약 1.1천만 명에게 최종 11분 정도 소요되고 있었다. (맨 처음에 이야기 한 순차적인 방법이였다면&amp;hellip; 훨씬더 오래 걸렸을꺼라 예상해본다&amp;hellip;)&lt;/p></description></item></channel></rss>