<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ko">
<generator uri="https://gohugo.io/" version="0.162.1">Hugo</generator>
<link href="https://sangwook.github.io/feed.xml" rel="self" type="application/atom+xml" />
<link href="https://sangwook.github.io/" rel="alternate" type="text/html" hreflang="ko" />
<updated>2021-01-01T00:00:01+09:00</updated>
<id>https://sangwook.github.io/</id>
<title type="html">이상욱</title>
<subtitle>프로그래머</subtitle>
<entry>
<title type="html">2020년</title>
<link href="https://sangwook.github.io/2021/01/01/tmi-2020.html" rel="alternate" type="text/html" title="2020년" />
<published>2021-01-01T00:00:01+09:00</published>
<updated>2021-01-01T00:00:01+09:00</updated>
<id>https://sangwook.github.io/2021/01/01/tmi-2020</id>
<content type="html" xml:base="https://sangwook.github.io/2021/01/01/tmi-2020.html">&lt;p&gt;2020년 한 해를 돌아봅니다. 평생 잊지 못할 1년으로 남을 것 같습니다. COVID-19 때문에 생활이 크게 바뀌었기 때문입니다. 내년 회고를 쓸 때쯤이면 이 상황이 어느 정도 해결되어 있기를 바랍니다.&lt;/p&gt;
&lt;p&gt;2020년은 경제적 자유를 이루었다는 확신이 생긴 해이기도 합니다. 지난 몇 년 동안은 이것이 운인지 아닌지를 늘 의심했습니다. 한두 해 잘된 결과를 곧바로 실력이라고 믿기는 어려웠습니다. 그래서 계속 운이 아닌지 물었습니다. 그리고 2020년에 확신이 생겼습니다. 조금 더 일찍 확신이 들었다면 좋았겠지만, 늦게 든 것이 오히려 잘된 일이라고 생각합니다. 확신이 생긴 뒤로 세계관이 꽤 바뀌었습니다. 그중 가장 좋은 변화는, 이기적인 사람에게도 너그러워질 수 있게 되었다는 점입니다.&lt;/p&gt;
&lt;p&gt;월세로 바꾸기로 하고, 실제로 옮겼습니다. 저는 웬만해서는 잘 움직이지 않는 사람입니다. 엉덩이가 아주 무거운 편입니다. 그런 저를 움직이게 할 만큼 분명한 장점이 보여서 결정을 내렸습니다. 연말에 이사를 했고, 지금은 매우 만족하고 있습니다. 조금 더 일찍 옮겼더라면 좋았을 거라고 생각합니다. 저는 무언가를 결정하기 전에 고민이 너무 많습니다.&lt;/p&gt;
&lt;p&gt;한 해 동안, 배워 두면 쓸모 있는 것이 무엇일까를 자주 생각했습니다. 이 답은 시기에 따라 자주 바뀝니다. 지금 시점의 생각으로는 통계, 프로그래밍, 영어, 운전의 순서입니다.&lt;/p&gt;
&lt;p&gt;회사 이야기입니다. COVID-19 때문에 거의 1년 내내 재택으로 일했습니다. 정확히는 2월 말부터입니다. 회사에서 한 일을 요약하면, 클라우드 플랫폼을 만드는 일이었습니다. 그 구름 너머에는 쿠버네티스와 go, knative, istio, helm, envoy 같은 것들이 있습니다. 더 자세히 적고 싶지만, 공개된 글에 정확히 쓰기는 조심스럽습니다. 솔직히 말하면, 자세히 풀어 쓰기가 조금 귀찮은 마음이 큽니다.&lt;/p&gt;
&lt;p&gt;건강 관련해서는 몸무게가 최근 15년을 통틀어 가장 높이 올라갔습니다. 재택근무는 살이 찌기에 좋은 환경입니다.&lt;/p&gt;
&lt;p&gt;한 해 동안 본 것들도 적어 둡니다. 영화와 드라마 중에서는 1917, 나이브스 아웃, 테넷, 소리도 없이, 콰이어트 플레이스, 나르코스, 나르코스 멕시코, 런, 800, 21이 기억에 남습니다. 그중 가장 재미있게 본 작품은 1917입니다.&lt;/p&gt;
&lt;p&gt;웹툰은 후기, 별종, 헬58, 도망자, 행성인간, 초인의 시대, 호랑이형님, 더 복서, 고수, 체크포인트, 헌팅, 피와 살, 수평선, 라스트 서브미션을 봤습니다. 그중 가장 기억에 남는 작품은 수평선입니다.&lt;/p&gt;
&lt;p&gt;인터넷 방송도 꽤 봤습니다. 침착맨님의 &lt;a href=&#34;https://www.youtube.com/watch?v=4k48gvdAsFY&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;삼국지 방송&lt;/a&gt;, &lt;a href=&#34;https://www.youtube.com/watch?v=TtnGyAayM2Y&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;배도라지 25시간 MT&lt;/a&gt;, 풍월량님의 데이 바이 데이라이트 방송이 기억에 남습니다. 주로 침착맨님과 풍월량님의 방송을 챙겨 봤습니다. 그중에서도 침착맨님의 삼국지 방송이 특히 좋았습니다. 어릴 때 삼국지 영걸전을 밤새워 하고 삼국지 책을 몇 번씩 다시 읽었던 비슷한 세대라서, 공감에서 오는 즐거움이 컸습니다.&lt;/p&gt;
&lt;p&gt;한 해를 보내며 가장 많이 한 생각은, 세상의 거의 모든 일이 취향의 문제라는 것입니다. 휴지를 앞으로 거는지 뒤로 거는지, 대답을 &amp;lsquo;네&amp;rsquo;로 하는지 &amp;lsquo;넵&amp;rsquo;으로 하는지, 어떤 종교를 믿는지, 정치 성향이 왼쪽인지 오른쪽인지, 아침형 인간인지 저녁형 인간인지, 코드에서 공백을 쓰는지 탭을 쓰는지, 무엇을 좋은 코드라고 부르는지조차 마찬가지입니다. 그 밖에도 살면서 발생하는 대부분의 문제가 그렇습니다.&lt;/p&gt;
&lt;p&gt;사람은 대체로 자기 취향이 옳고 남의 취향은 틀렸다고 생각합니다. 그리고 많은 사람이 죽을 때까지 그 생각을 바꾸지 않습니다. 하지만 그것이 옳고 그름의 문제가 아니라 취향의 문제라고 받아들이면, 보이는 풍경이 달라집니다. 상대의 취향을 존중하는 자세로 대화하면, 화를 내는 일도 다투는 일도 갈등도 줄어든다고 생각합니다. 곰곰이 따져 보면 남에게 정말로 화를 내야 할 일은 의외로 많지 않습니다. 대부분은 그저 취향의 차이이기 때문입니다.&lt;/p&gt;
&lt;p&gt;2021년에는 COVID-19 상황이 가라앉아서, 다시 평범한 일상을 보낼 수 있기를 바랍니다.&lt;/p&gt;
</content>
<author><name></name></author>
<summary type="html">2020년 한 해를 돌아봅니다. 평생 잊지 못할 1년으로 남을 것 같습니다. COVID-19 때문에 생활이 크게 바뀌었기 때문입니다. 내년 회고를 쓸 때쯤이면 이 상황이 어느 정도 해결되어 있기를 바랍니다.
2020년은 경제적 자유를 이루었다는 확신이 생긴 해이기도 합니다. 지난 몇 년 동안은 이것이 운인지 아닌지를 늘 의심했습니다. 한두 해 잘된 결과를 …</summary>
</entry>
<entry>
<title type="html">2019년</title>
<link href="https://sangwook.github.io/2020/01/01/tmi-2019.html" rel="alternate" type="text/html" title="2019년" />
<published>2020-01-01T00:00:01+09:00</published>
<updated>2020-01-01T00:00:01+09:00</updated>
<id>https://sangwook.github.io/2020/01/01/tmi-2019</id>
<content type="html" xml:base="https://sangwook.github.io/2020/01/01/tmi-2019.html">&lt;p&gt;2019년을 돌아봅니다. 한 해 동안 시장이 아주 좋았습니다. 제가 기준으로 삼는 벤치마크가 16% 가까이 올랐습니다. 세계 자본주의 자산 시장이 그만큼 팽창했다는 뜻입니다. 무언가를 사 두고 가만히 있기만 해도 평균적으로 그 정도 수익을 얻을 수 있었다는 뜻이기도 합니다. 그만큼 2019년은 시장이 좋은 해였습니다. 시장이 좋은 해에는 한 가지 기분을 경계하게 됩니다. 나를 두고 버스가 떠나는 것 같은 조급함입니다. 그 기분은 대체로 시장이 고점에 가까워졌다는 신호입니다.&lt;/p&gt;
&lt;p&gt;한 해 동안 읽은 책과 논문을 돌아봤습니다. 논문을 읽는 데 시간을 많이 썼다고 생각했습니다. 그런데 돌아보니, 사실은 한 편의 논문을 수십 번씩 다시 읽고 있었습니다. 어쩌면 수백 번이었을지도 모릅니다. 그래서 올해 읽은 논문과 책의 수를 세어 보면 한 손으로 충분합니다. 여전히 알고 싶은 것이 많습니다. 그보다 모르는 것이 훨씬 많습니다. 시간이 얼마나 더 지나야 이것이 운인지 아닌지 확신이 서고, 더 공부할 것이 없다는 생각이 들지 궁금합니다.&lt;/p&gt;
&lt;p&gt;자본주의는 인간이 이기적이라는 공리 위에 세워진 시스템입니다. 인간의 본성을 토대로 삼은 시스템은 오래갑니다.&lt;/p&gt;
&lt;p&gt;SNS와 뉴스를 보지 않기로 정한 뒤로 시간이 많아졌습니다. 그 시간을 의미 있다고 생각하는 일에 쓰려고 노력했습니다. 저에게 의미 있는 일은, 노동으로 버는 수입을 자본으로 버는 수입으로 바꾸는 문제를 고민하는 것입니다. 그렇게 지내다 보니, 많은 사람이 의미 없어 보이는 일에 에너지를 쏟고 있다는 생각이 들었습니다.&lt;/p&gt;
&lt;p&gt;올해 가장 재미있게 본 영화도 기생충이었습니다. 그 영화를 보고 나서, 사람들이 대체로 자신과 같은 계급의 사람과 다툰다는 생각을 했습니다. 지하철을 탄 사람은 같은 지하철을 탄 사람과 다툽니다. 버스가 늦게 온다며 버스 기사에게 &lt;a href=&#34;https://news.v.daum.net/v/20191213210813280&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;폭언을 하기도 합니다&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;회사도 비슷합니다. 회사 안의 여러 제도와 시스템도 자본의 효율을 높이는 방향으로 오랜 시간 다듬어져 왔습니다. 출퇴근과 직급, 평가 같은 구조도 그 흐름의 일부로 보입니다. 이 시스템 역시 인간의 본성 위에 서 있기에, 쉽게 사라지지 않을 것입니다.&lt;/p&gt;
&lt;p&gt;악플은 어디서나 쉽게 볼 수 있습니다. 악플과 같은 심리에서 나오는, 특정한 대상을 향한 비난도 SNS에 흔합니다. 그런데 악플을 비난하는 이 문장 역시 일종의 악플이고, 저 또한 악플을 쓰는 사람과 같은 심리인 것은 아닐까 하는 생각이 듭니다. 이렇게까지 따라가면 결국 모든 것이 의미 없다는 결론에 이릅니다. 어쩌면 사람들은 자신의 상황이 좋지 않아 마음이 좁아져 있고, 그래서 남에게 엄격한 것인지도 모릅니다. 빈부의 격차가 줄어들면, 남에게 너그러운 사람이 다수가 될까요.&lt;/p&gt;
&lt;p&gt;웹툰 이야기도 적어 둡니다. &lt;a href=&#34;https://comic.naver.com/webtoon/list.nhn?titleId=119874&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;덴마&lt;/a&gt;는 아쉽게도 실망스러운 결말로 끝날 것 같습니다. &lt;a href=&#34;http://webtoon.daum.net/webtoon/view/eternallight2&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;영원한 빛&lt;/a&gt;은 올해 완결되었습니다. 첫 화가 나왔을 때부터 재미있게 봤기에, 끝나고 나니 아쉬움이 큽니다. 제가 본 가장 좋은 웹툰 가운데 하나로 오래 기억될 것 같습니다.&lt;/p&gt;
&lt;p&gt;회사에서는 한 해 동안 쿠버네티스를 다루는 일을 했습니다. 내년에도 쿠버네티스와 관련된 일을 하지만, 조금은 다른 일이 될 것 같습니다. 무슨 일을 했는지는 2020년 회고에서 요약해 보겠습니다.&lt;/p&gt;
&lt;p&gt;다음 회고는 2021년 1월에 이어집니다. 그때쯤이면 운인지 아닌지에 대한 확신이 서 있기를 바랍니다.&lt;/p&gt;
</content>
<author><name></name></author>
<summary type="html">2019년을 돌아봅니다. 한 해 동안 시장이 아주 좋았습니다. 제가 기준으로 삼는 벤치마크가 16% 가까이 올랐습니다. 세계 자본주의 자산 시장이 그만큼 팽창했다는 뜻입니다. 무언가를 사 두고 가만히 있기만 해도 평균적으로 그 정도 수익을 얻을 수 있었다는 뜻이기도 합니다. 그만큼 2019년은 시장이 좋은 해였습니다. 시장이 좋은 해에는 한 가지 기분을 경 …</summary>
</entry>
<entry>
<title type="html">2018년</title>
<link href="https://sangwook.github.io/2019/03/23/tmi.html" rel="alternate" type="text/html" title="2018년" />
<published>2019-03-23T22:28:55+09:00</published>
<updated>2019-03-23T22:28:55+09:00</updated>
<id>https://sangwook.github.io/2019/03/23/tmi</id>
<content type="html" xml:base="https://sangwook.github.io/2019/03/23/tmi.html">&lt;p&gt;2018년이 끝나고 2019년이 되었습니다. 원래는 2018년 회고를 따로 남기고 싶었습니다. 스페인에 다녀온 이야기, 그리고 생각이 크게 달라진 일을 적어 두고 싶었습니다. 하지만 결국 생각에 그치고 말았습니다.&lt;/p&gt;
&lt;p&gt;돌아보면 1년 전이나 2년 전에는 지금의 저를 상상할 수 없었습니다. 지금도 1년 뒤, 2년 뒤의 저를 그려 보기는 어렵습니다. 그래서 1년에 한 번이라도 큰 사건이나 그때의 감정을 적어 두는 일이 미래의 저에게 도움이 된다고 생각합니다. 무척 귀찮은 일이지만, 1년에 한 번 정도는 할 수 있을 것 같습니다.&lt;/p&gt;
&lt;p&gt;새해 다짐으로 한 달 단위로 결산을 하고 있습니다. 그 내용을 &lt;a href=&#34;https://blog.naver.com/yiisw&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;블로그&lt;/a&gt;에 가볍게 적어 둡니다. 적다 보니 여러 가지 좋은 점이 있었습니다. 귀찮아질 때까지는 최대한 적어 보려 합니다.&lt;/p&gt;
&lt;p&gt;이 글도 부담 없이, 떠오르는 대로 한 번에 적어 내려가려 합니다. 우선 근황부터 적습니다. SNS를 하지 않기로 했습니다. 뉴스도 잘 보지 않고 있습니다. 물론 특정 분야의 뉴스는 여전히 많이 읽습니다. 어느 날 갑자기, SNS와 뉴스에 시간을 쓰는 일이 무의미하게 느껴졌습니다. 그 무렵부터 &amp;lsquo;이것이 나에게 의미가 있는가&amp;rsquo;라는 질문을 자주 하게 되었습니다.&lt;/p&gt;
&lt;p&gt;뉴스는 멀리하게 되었지만, 최근 열린 FOMC 회의에는 휴가를 내고 관련 글을 찾아 읽을 만큼 관심이 컸습니다. 아주 중요한 신호가 나왔습니다. 한국과 미국의 채권시장은 이를 미리 반영해 두었다고 생각했는데, 발표 이후 더 급하게 움직였습니다. 그리고 올해 9월을 눈여겨보게 되었습니다.&lt;/p&gt;
&lt;p&gt;몇 년 동안 특정 분야의 논문을 많이 읽었습니다. 제 전공이 아니다 보니, 논문 한 편을 읽기 위해 필요한 사전 지식이 계속 늘어났습니다. 그렇게 어렵게 끝까지 읽고 이해하고 나면, 정작 결론은 단순한 경우가 많았습니다.&lt;/p&gt;
&lt;p&gt;생각해 보면 지금 제가 하는 일은, 무언가를 끊임없이 단순하게 만들고, 신호를 키우고, 잡음을 줄이는 일로 요약할 수 있습니다. 한 가지 느낀 점은, 수학적인 토대에서 오는 심리적인 안정감이 무척 크다는 것입니다.&lt;/p&gt;
&lt;p&gt;그리고 이 분야뿐 아니라 어느 분야에서나, 편견을 걷어 내고 남이나 상황을 탓하지 않는 자세가 중요하다고 생각합니다. 그래야 더 깊이 고민할 수 있고, 합리화로 고민을 멈춰 버리는 일이 없어집니다. 편견과 남 탓은 인간의 본능이고, 어디서나 흔히 볼 수 있습니다. 당연한 일입니다. 어쩌면 그것이 있기에 인간이 마음을 지키며 살아갈 수 있는 것인지도 모릅니다.&lt;/p&gt;
&lt;p&gt;해마다 연초가 되면 제 마음을 흔드는 일이 생깁니다. 매번 처음에는 멍하니 있다가, 시간이 지나면서 회복되곤 했습니다. 그런데 올해는 아직 회복되지 않을 만큼 상처가 큽니다. 시간이 조금 더 필요한 것 같습니다. 아버지가 편찮으셨고, 개인적인 일도 있었습니다. 지금 아버지는 퇴원하셨고, 큰 고비는 다행히 지나가고 있는 듯합니다. 건강이 가장 중요합니다.&lt;/p&gt;
&lt;p&gt;올해 이렇게 한 번 적었으니, 1년 뒤에 다시 적어 보겠습니다.&lt;/p&gt;
</content>
<author><name></name></author>
<summary type="html">2018년이 끝나고 2019년이 되었습니다. 원래는 2018년 회고를 따로 남기고 싶었습니다. 스페인에 다녀온 이야기, 그리고 생각이 크게 달라진 일을 적어 두고 싶었습니다. 하지만 결국 생각에 그치고 말았습니다.
돌아보면 1년 전이나 2년 전에는 지금의 저를 상상할 수 없었습니다. 지금도 1년 뒤, 2년 뒤의 저를 그려 보기는 어렵습니다. 그래서 1년에 …</summary>
</entry>
<entry>
<title type="html">쿠버네티스 코드 읽기</title>
<link href="https://sangwook.github.io/2018/06/19/kubernetes-k8s-code.html" rel="alternate" type="text/html" title="쿠버네티스 코드 읽기" />
<published>2018-06-19T22:26:00+09:00</published>
<updated>2018-06-19T22:26:00+09:00</updated>
<id>https://sangwook.github.io/2018/06/19/kubernetes-k8s-code</id>
<content type="html" xml:base="https://sangwook.github.io/2018/06/19/kubernetes-k8s-code.html">&lt;p&gt;요즘은 쿠버네티스(이하 k8s) 소스 코드를 읽고 있습니다. 디자인이 단순한 덕분에 비교적 읽기가 어렵지 않습니다. k8s가 이만큼 인기를 얻은 것도 그 단순함 때문일 것입니다.&lt;/p&gt;
&lt;p&gt;디자인이 이렇게 단순해진 데에는 etcd의 역할이 컸다고 생각합니다. k8s는 etcd를 작업 큐(task queue)처럼 사용합니다. 메소스(mesos)는 같은 자리에 주키퍼(zookeeper)를 두는데, 바로 이 선택의 차이가 두 시스템을 크게 갈라놓은 것이 아닐까 싶습니다.&lt;/p&gt;
&lt;p&gt;제가 오래전에 분석할 때만 해도 &amp;lsquo;미니언&amp;rsquo;이라는 용어를 쓰더니, 어느새 &amp;lsquo;노드&amp;rsquo;로 바뀌었습니다. &amp;lsquo;노드&amp;rsquo;라는 이름 덕분에, 그것이 무엇을 하는 것인지 따로 설명할 필요가 없어졌습니다. 이름을 바꾸던 무렵에 &lt;a href=&#34;https://github.com/kubernetes/kubernetes/issues/1111&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;올라온 후보들&lt;/a&gt;을 보면 Koupi, Rower, Krew 같은 것이 있었습니다. &amp;lsquo;항해&amp;rsquo;에 빗대고 싶은 마음이 꽤 컸던 모양입니다. 하지만 비유나 추상보다는 구체적인 용어가 낫다고 생각합니다.&lt;/p&gt;
&lt;h2 id=&#34;쿠버네티스를-소스에서-빌드&#34;&gt;쿠버네티스를 소스에서 빌드&lt;/h2&gt;
&lt;p&gt;저는 제가 쓰는 솔루션을 직접 빌드해서 쓰는 것을 좋아합니다. 물론 제 개발 환경에 한해서입니다. 예를 들어 MySQL을 자주 쓰다 보니, 코드를 조금 손봐서 직접 빌드한 것을 씁니다. 문서를 읽기보다는 코드를 읽고, 로그를 찍어 보고, 직접 돌려 봅니다.&lt;/p&gt;
&lt;p&gt;이렇게 하면 장점이 아주 많습니다. 아마 직접 해 본 사람만 느낄 수 있는 종류의 장점입니다. 리눅스 데스크톱을 운영체제로 쓰는 것, 그리고 vim을 쓰는 것도 장점이 무척 크다고 생각합니다. 그런데 막상 그 이유를 설명해 보라고 하면 말로 풀어내기가 어렵습니다. 사실 그 장점을 누리려면 수많은 문제를 스스로 해결해야 하기 때문이기도 합니다.&lt;/p&gt;
&lt;p&gt;저 같은 이상한 사람을 그동안 본 적이 없었습니다. 그런데 회사에서 점심을 먹고 산책하다가, yan님에게도 비슷한 취미가 있다는 것을 알게 되었습니다. 좋게 말해 취미일 뿐, 사실은 고약한 버릇에 가깝습니다. vim 애호가로 수렴한 사람들은 결국 비슷한 길을 걷게 되는 것일까요.&lt;/p&gt;
&lt;p&gt;아무튼 k8s도 궁금한 부분에 로깅을 더해 빌드하고, 제가 빌드한 버전으로 하나씩 갈아 끼우는 작업을 하고 있습니다. 저와 같은 생각을 하는 사람이라면 십중팔구 &lt;code&gt;kubectl&lt;/code&gt; 수정부터 시작할 것입니다.&lt;/p&gt;
&lt;h2 id=&#34;kubectl-빌드&#34;&gt;&lt;code&gt;kubectl&lt;/code&gt; 빌드&lt;/h2&gt;
&lt;p&gt;빌드 스크립트를 따라가 보면 &lt;code&gt;cmd/kubectl&lt;/code&gt;을 빌드한다는 것을 알 수 있습니다. 별생각 없이 일단 빌드를 돌려 보면 1시간쯤 걸립니다. 그 결과로 아래와 같은 바이너리가 만들어집니다.&lt;/p&gt;
&lt;div class=&#34;highlighter-rouge&#34;&gt;&lt;pre class=&#34;highlight&#34;&gt;&lt;code&gt;-rwxr-xr-x 1 sangwook sangwook 201M  6월 11 22:39 kube-apiserver
-rwxr-xr-x 1 sangwook sangwook  65M  6월 11 22:40 kubectl
-rwxr-xr-x 1 sangwook sangwook 141M  6월 11 22:39 kubelet
...&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;코드를 한 번 고칠 때마다 빌드에 1시간을 기다려야 했습니다. 저는 쿠버네티스를 잘 모르는 사람이라, 모르면 이 정도는 참아야 한다고 여겼습니다. 빌드 스크립트를 파고드는 것이 목적은 아니었으니까요.&lt;/p&gt;
&lt;p&gt;그러다 도저히 참지 못하고, 시간을 내어 빌드 스크립트를 읽었습니다. 그 덕에 빌드 시간을 9분에서 10분 정도로 줄였습니다. 이마저도 느려서 견디기 힘들지만, 더 빠르게 만드는 일은 시간이 남을 때 하기로 미뤄 두었습니다.&lt;/p&gt;
&lt;p&gt;하지만 결국 10분을 기다리는 것조차 참지 못하고, 빌드 스크립트를 좀 더 자세히 들여다봤습니다. 예전에는 테스트 코드를 건너뛰는 옵션이 있었던 것 같은데, 지금은 그 옵션이 동작하지 않았습니다. 일단은 10분을 기다리는 쪽으로 타협했습니다.&lt;/p&gt;
&lt;p&gt;kubespray가 kubectl과 kubelet을 업데이트하는 방식은 이렇습니다. hyperkube 이미지 안의 kubectl과 호스트의 kubectl을 바이트 단위로 비교한 뒤, 둘이 다르면 복사합니다. 이 부분은 &lt;a href=&#34;https://github.com/sangwook/kubespray/blob/3d6fd491795adb8a38493afe6c2968a46051d5ff/roles/kubernetes/master/tasks/main.yml#L32&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;kubespray 코드&lt;/a&gt;에서 볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;이제 제가 빌드한 kubectl을 쓰도록 바이너리 경로를 바꿉니다. 그다음 클러스터의 config를 &lt;code&gt;~/.kube/sangwook-cluster.conf&lt;/code&gt;로 복사하고, &lt;code&gt;KUBECONFIG&lt;/code&gt;에 그 config 경로를 지정합니다. 이렇게 해 두면 kubectl 명령을 실행하면서 테스트할 수 있습니다.&lt;/p&gt;
&lt;h2 id=&#34;apiserver-빌드&#34;&gt;&lt;code&gt;apiserver&lt;/code&gt; 빌드&lt;/h2&gt;
&lt;p&gt;apiserver 빌드는 의외로 간단합니다. 도커 이미지만 만든 다음 이미지 주소를 바꾸면 됩니다. apiserver가 static pod로 정의되어 있어서, 주소를 바꾸면 manifest가 곧바로 적용됩니다. 도커 이미지를 만드는 데에는 몇 초밖에 걸리지 않습니다. hyperkube 하나만 만들면 10초쯤입니다.&lt;/p&gt;
&lt;p&gt;이렇게 자주 수정하고 빌드하고 도커 이미지를 만들다 보면, 지금 돌고 있는 것이 방금 빌드한 버전이 맞는지 궁금해질 때가 있습니다. 제대로 배포가 되긴 한 것인지 확인하고 싶어지는 것입니다. 그럴 때는 빌드한 서버에서 &lt;code&gt;docker images --digests&lt;/code&gt;를 실행해 digest의 sha256 값을 확인합니다.&lt;/p&gt;
&lt;div class=&#34;highlighter-rouge&#34;&gt;&lt;pre class=&#34;highlight&#34;&gt;&lt;code&gt;  REPOSITORY               TAG                    DIGEST                                                                  IMAGE ID     CREATED        SIZE
  sangwook/hyperkube-amd64 v1.9.5-sangwook-custom sha256:71d332a5b8cdb21329b9ca75c5aae454fa3d60c8a87b6088aaeee1720a8850f4 944446664a2b 32 minutes ago 619MB&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;그리고 apiserver를 배포한 서버에서 나오는 digest의 sha256이 이 값과 같은지 확인하면 됩니다. 여기서 IMAGE ID가 아니라 digest를 본다는 점이 핵심입니다.&lt;/p&gt;
&lt;div class=&#34;highlighter-rouge&#34;&gt;&lt;pre class=&#34;highlight&#34;&gt;&lt;code&gt;  CONTAINER ID IMAGE                                                                                             COMMAND               CREATED        STATUS
  0b11ac196ea3 sangwook/hyperkube-amd64@sha256:71d332a5b8cdb21329b9ca75c5aae454fa3d60c8a87b6088aaeee1720a8850f4 &amp;#34;/hyperkube apiser...&amp;#34; 13 minutes ago Up 13 minutes&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h2 id=&#34;etcd에-업데이트&#34;&gt;&lt;code&gt;etcd&lt;/code&gt;에 업데이트&lt;/h2&gt;
&lt;p&gt;etcd와 통신하는 로직이 궁금해서 코드를 따라가 봤습니다. 이렇게 코드를 따라가다 보면 스택을 자주 확인하게 되고, 스택의 각 지점에 해당하는 코드로 손쉽게 옮겨 다닐 수 있어야 합니다. 그래서 아래와 같은 vim 플러그인을 직접 만들어 쓰고 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/assets/2018/180619-vim-9f3e9941dc41c9ce800421e81a483fe22b8fa36a4233a39a30b1bb950b390f5f.gif&#34; alt=&#34;이미지&#34;&gt;&lt;/p&gt;
&lt;p&gt;처음에는 &lt;code&gt;kubectl get pods&lt;/code&gt; 같은 get 로직을 따라가 봤는데, 기억에 남을 만큼 특별한 점은 없었습니다. 그래서 etcd 변경이 일어나는 쪽을 봤습니다. 예를 들어 service의 nodePort를 kubectl로 바꾸면, 변경된 spec의 셀렉터와 바뀐 값만 request body에 담아 apiserver로 PATCH 요청을 보냅니다. apiserver는 그 요청을 받아 etcd를 업데이트합니다.&lt;/p&gt;
&lt;p&gt;코드를 보다 보면 etcd를 덤프해서 변경 전후를 diff 하는 일을 자꾸 반복하게 됩니다. 처음에는 제대로 된 덤프 방법을 몰라서, key 목록을 가져온 뒤 하나씩 get하는 스크립트를 만들어 써야 했습니다. 분명 더 좋은 방법이 있을 것입니다. 지금은 etcd 값이 바뀌면 메시지를 받도록 k8s를 고쳤는데, 이 편이 훨씬 편했습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/assets/2018/180619-etcddump1-a96e434accf60983f0408b6413137ac1824f1ce2c90b450700c27bc91a5fbf0c.gif&#34; alt=&#34;이미지&#34;&gt;&lt;/p&gt;
&lt;p&gt;etcd에 저장하는 로직에서 재미있게 본 코드를 몇 군데 적어 둡니다. 리소스 업데이트는 모두 &lt;a href=&#34;https://github.com/sangwook/kubernetes/blob/f01a2bf98249a4db383560443a59bed0c13575df/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go#L101-L107&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;이 거대한 메소드&lt;/a&gt; 안으로 들어옵니다. 그리고 &lt;a href=&#34;https://github.com/sangwook/kubernetes/blob/f01a2bf98249a4db383560443a59bed0c13575df/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go#L182-L186&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;이 코드&lt;/a&gt;를 거쳐, etcd 업데이트를 끝까지 따라가면 &lt;a href=&#34;https://github.com/sangwook/kubernetes/blob/f01a2bf98249a4db383560443a59bed0c13575df/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go#L263&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;이 지점&lt;/a&gt;에 이릅니다.&lt;/p&gt;
&lt;p&gt;사실 저장하는 부분보다는 notify와 watch를 하는 부분이 핵심입니다. 그 밖에도 apiserver와 scheduler가 통신하는 로직, apiserver와 kubelet이 통신하는 로직이 흥미로웠습니다. &lt;code&gt;kubectl create -f xxx.yaml&lt;/code&gt;로 Service를 nodePort로 생성할 때 services와 endpoints에 각각 한 번씩 모두 두 번의 POST를 보내고, 그에 맞춰 iptables를 바꾸는 로직도 재미있었습니다.&lt;/p&gt;
&lt;p&gt;이런 것을 모두 여기에 정리하려니 벅찹니다. 게다가 저처럼 사소한 데에 마음을 쓰는 사람이 많지는 않을 것 같습니다. 그래서 오늘은 여기까지 적습니다.&lt;/p&gt;
</content>
<author><name></name></author>
<summary type="html">요즘은 쿠버네티스(이하 k8s) 소스 코드를 읽고 있습니다. 디자인이 단순한 덕분에 비교적 읽기가 어렵지 않습니다. k8s가 이만큼 인기를 얻은 것도 그 단순함 때문일 것입니다.
디자인이 이렇게 단순해진 데에는 etcd의 역할이 컸다고 생각합니다. k8s는 etcd를 작업 큐(task queue)처럼 사용합니다. 메소스(mesos)는 같은 자리에 주키퍼 …</summary>
</entry>
<entry>
<title type="html">스탠딩 데스크</title>
<link href="https://sangwook.github.io/2018/01/03/standing-motion-desk.html" rel="alternate" type="text/html" title="스탠딩 데스크" />
<published>2018-01-03T23:55:00+09:00</published>
<updated>2018-01-03T23:55:00+09:00</updated>
<id>https://sangwook.github.io/2018/01/03/standing-motion-desk</id>
<content type="html" xml:base="https://sangwook.github.io/2018/01/03/standing-motion-desk.html">&lt;p&gt;스탠딩 데스크를 샀습니다. 정확히는 일룸 데스커에서 만든 &lt;a href=&#34;http://www.desker.co.kr/product/DSMD712D&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;모션 데스크&lt;/a&gt;입니다. 이제 한 달 넘게 썼습니다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=avmMKnkgEw4&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;정창훈님의 유튜브 리뷰&lt;/a&gt;를 재미있게 봤지만, 책상이 너무 무거울까 싶어 한동안 망설였습니다. 그러다 우연히 김재현님을 만났는데, 강력히 추천해 주셔서 주문했습니다. 그러고 보니 &lt;a href=&#34;https://medium.com/n42-corp/%EC%84%9C%EC%84%9C-%EC%9D%BC%ED%95%98%EA%B8%B0-%EC%9C%84%ED%95%9C-%EC%8A%A4%ED%83%A0%EB%94%A9-%EB%8D%B0%EC%8A%A4%ED%81%AC-7e07717c4229&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;당근마켓 분들도 모두 스탠딩 데스크를 쓰는 듯합니다&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;지금 다니는 회사에서는 이사할 때 옮기기 불편하다는 이유로 전동 스탠딩 데스크를 두지 않습니다. 대신 베리데스크를 씁니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/assets/2018/180103-varidesk-9d14e1d7cda7bb2b86e8ab231a093a65fb2dcc98302ea2a9655d17cfa0a86f7a.jpg&#34; alt=&#34;이미지&#34;&gt;&lt;/p&gt;
&lt;p&gt;베리데스크는 높이를 미세하게 맞출 수 없다는 점이 단점입니다. 제 눈높이에 맞춰 가장 높게 올려 두면 키보드 위치가 너무 낮아집니다. 그렇게 오래 쓰다 보니 손목이 아파 병원까지 다녀왔습니다. 원인이 베리데스크였고, 서서 일할 때는 키보드와 마우스 밑에 받침을 두어야 통증이 없었습니다.&lt;/p&gt;
&lt;p&gt;일룸 데스커 모션 데스크에는 크게 만족하고 있습니다. 책상 높이를 미세하게 조절할 수 있습니다. 어차피 저 혼자 쓰니 한 위치에 거의 그대로 두게 되긴 합니다. 저는 40분 앉아 있다가 20분 서 있는 것을 반복합니다. 이렇게 자주 오르내릴 때는 버튼을 계속 누르고 있어야 높이가 움직이는 점이 살짝 불편합니다. 7만 원을 더 내면 앱으로 높이를 기억해 자동으로 맞춰 주는 기능(스마트컨트롤 옵션)이 있습니다. 아주 편할 것 같긴 한데, 7만 원이라니 망설이게 됩니다.&lt;/p&gt;
&lt;p&gt;40분 앉고 20분 서는 주기를 알리도록 아래 스크립트를 만들어 쓰고 있습니다.&lt;/p&gt;
&lt;div class=&#34;highlighter-rouge&#34;&gt;&lt;pre class=&#34;highlight&#34;&gt;&lt;code&gt;#!/usr/bin/env ruby
raise unless /linux/ =~ RUBY_PLATFORM
require &amp;#39;libnotify&amp;#39;
require &amp;#39;timers&amp;#39;
raise if ARGV.empty?
timeout_min = ARGV[0].to_i
timers = Timers::Group.new
min = 0
timers.now_and_every(60) do
  min &amp;#43;= 1
  puts &amp;#34;#{Time.now.strftime(&amp;#39;%Y-%m-%d %H:%M&amp;#39;)} #{min}&amp;#34;
  system &amp;#34;tmux rename-window -t${TMUX_PANE} &amp;#39;#{min}&amp;#39;&amp;#34; if ENV.key? &amp;#39;TMUX&amp;#39;
  if min &amp;gt; timeout_min
    Libnotify.show summary: &amp;#39;timeout&amp;#39;
    exit 0
  end
end
loop { timers.wait }&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;/assets/2018/180103-timer-d2d36ae0e907d2c40a79ec63432d5814c35e94ddf719d66a7dd12e20c6d8f71d.gif&#34; alt=&#34;이미지&#34;&gt;&lt;/p&gt;
&lt;p&gt;shell에서 &lt;code&gt;40&lt;/code&gt;을 입력하면 40분 뒤에 timeout 알림창이 뜨고, &lt;code&gt;20&lt;/code&gt;을 입력하면 20분 뒤에 뜨도록 해 두었습니다. 다른 tmux window를 보고 있어도 남은 시간을 알 수 있게 &lt;code&gt;tmux rename-window&lt;/code&gt;로 윈도우 이름을 갱신하게 했습니다. 위 스크린캐스트는 시연이라 &lt;code&gt;3&lt;/code&gt;을 입력해 3초 뒤에 알림이 뜨도록 한 것입니다.&lt;/p&gt;
</content>
<author><name></name></author>
<summary type="html">스탠딩 데스크를 샀습니다. 정확히는 일룸 데스커에서 만든 모션 데스크입니다. 이제 한 달 넘게 썼습니다.
정창훈님의 유튜브 리뷰를 재미있게 봤지만, 책상이 너무 무거울까 싶어 한동안 망설였습니다. 그러다 우연히 김재현님을 만났는데, 강력히 추천해 주셔서 주문했습니다. 그러고 보니 당근마켓 분들도 모두 스탠딩 데스크를 쓰는 듯합니다.
지금 다니는 회사에서는 …</summary>
</entry>
<entry>
<title type="html">kubernetes, python, kafka 메모</title>
<link href="https://sangwook.github.io/2017/08/27/kubernetes-python-kafka.html" rel="alternate" type="text/html" title="kubernetes, python, kafka 메모" />
<published>2017-08-27T11:00:00+09:00</published>
<updated>2017-08-27T11:00:00+09:00</updated>
<id>https://sangwook.github.io/2017/08/27/kubernetes-python-kafka</id>
<content type="html" xml:base="https://sangwook.github.io/2017/08/27/kubernetes-python-kafka.html">&lt;h2 id=&#34;kubernetes&#34;&gt;kubernetes&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://github.com&lt;/a&gt; 이 kubernetes 위에서 100% 돌아가도록 이전했다고 합니다. &lt;a href=&#34;https://githubengineering.com/kubernetes-at-github/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;githubengineering&lt;/a&gt; 정확히는 rails 웹앱을 모두 kubernetes 클러스터의 컨테이너에 올렸다는 이야기입니다. 일단 kubernetes 성공 사례라서 반가웠고, 추상적인 이야기가 아니라 실용적인 내용이 많아서 더 좋았습니다. 예를 들어 커널 패닉에 대한 실패 테스트를 만들기 위해 &lt;code&gt;echo c &amp;gt; /proc/sysrq-trigger&lt;/code&gt; 명령을 사용했다는 식의 구체적인 사례가 인상에 남습니다.&lt;/p&gt;
&lt;h2 id=&#34;python&#34;&gt;python&lt;/h2&gt;
&lt;p&gt;최근에는 python을 많이 사용했습니다. ruby로는 풀리지 않는 상황이었고, python을 피할 수 없는 경우를 여러 번 겪었습니다. 마침 python3.6이 나쁘지 않아서, &amp;ldquo;만약 평생 하나의 프로그래밍 언어만 배워야 한다면 python이 맞지 않을까?&amp;rdquo; 같은 이야기를 저도 하게 되었습니다.&lt;/p&gt;
&lt;p&gt;python이 ruby보다 확실히 좋다고 느낀 점도 있습니다. built-in &lt;code&gt;logging&lt;/code&gt; 모듈이 더 좋았고, &lt;code&gt;argparse&lt;/code&gt; 모듈은 ruby의 &lt;code&gt;optparse&lt;/code&gt; 보다 훨씬 더 잘 만들어져 있습니다.&lt;/p&gt;
&lt;p&gt;반면 &lt;code&gt;&#39;,&#39;.join([&#39;1&#39;,&#39;2&#39;]) # =&amp;gt; &#39;1,2&#39;&lt;/code&gt; 같은 표기는 여전히 헷갈립니다. &lt;code&gt;[&#39;1&#39;,&#39;2&#39;].join(&#39;,&#39;) # =&amp;gt; &#39;1,2&#39;&lt;/code&gt; 처럼 Array에 join 메소드가 있는 ruby가 저에게는 더 자연스럽습니다. python은 &lt;code&gt;int(&#39;1&#39;)&lt;/code&gt; 처럼 함수로 감싸는 형태로 코드를 작성하는 경향이 있는 것 같습니다. ruby처럼 &lt;code&gt;&#39;1&#39;.to_i&lt;/code&gt; 가 커서 이동도 적고 직관적으로 느껴집니다. python 린터(autopep8, flake8)는 ruby의 린터보다 관대하다는 인상을 받았습니다. ruby가 과도하게 엄격한 것일지도 모르겠습니다.&lt;/p&gt;
&lt;p&gt;python3.6 부터는 숫자에 밑줄을 넣을 수 있게 되었습니다. ruby는 린터에서 &lt;code&gt;1000000&lt;/code&gt; 대신 &lt;code&gt;1_000_000&lt;/code&gt; 을 쓰라고 안내합니다. &lt;a href=&#34;https://github.com/bbatsov/ruby-style-guide#underscores-in-numerics&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;github&lt;/a&gt; &lt;code&gt;1000000&lt;/code&gt; 은 읽기 어렵고 &lt;code&gt;1_000_000&lt;/code&gt; 은 읽기 쉬우니까요. python은 그동안 이 기능이 안 되어서 불편함을 참아 왔는데, 최근 도저히 견디기 힘든 코드를 보고 혹시나 하고 찾아보니 pep-515로 제안되어 python3.6 부터 반영되어 있었습니다. &lt;a href=&#34;https://www.python.org/dev/peps/pep-0515/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;python&lt;/a&gt; 그러다 이 pep 문서를 읽으며 java도 같은 문법이 가능하다는 사실을 알게 되었습니다. 그것도 꽤 오래전부터 그렇다고 합니다. &lt;a href=&#34;https://docs.oracle.com/javase/7/docs/technotes/guides/language/underscores-literals.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;oracle&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;python을 만든 Guido 형이 2009년에 쓴 &amp;ldquo;파이썬 함수형 기능의 기원&amp;quot;이라는 글도 읽었습니다. &lt;a href=&#34;http://python-history.blogspot.kr/2009/04/origins-of-pythons-functional-features.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;blogspot&lt;/a&gt; &amp;ldquo;파이썬이 함수형 언어에서 크게 영향을 받았다고 생각한 적이 없다&amp;quot;로 시작하는 재미있는 글입니다. 그동안 파이썬의 함수형 스타일에서 약간 어색하게 느껴졌던 부분이 있었는데, 이 글을 읽고 어느 정도 이해가 되었습니다.&lt;/p&gt;
&lt;p&gt;python3.6 에서 추가된 syntax 중에서는 f-string을 특히 좋아합니다. 그런데 vim 기본 syntax 파일에서는 이 문법이 제대로 지원되지 않고, 숫자의 underscore 같은 것도 제대로 표시되지 않습니다. 새로운 syntax 파일을 설치하니 잘 표시됩니다. &lt;a href=&#34;https://github.com/vim-python/python-syntax&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;github&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/assets/2017/170801-3-bfa70f9116ff6a3f16ff8da581678a06760190bb8a585c2c48ff896874ee08f3.png&#34; alt=&#34;이미지&#34;&gt;&lt;/p&gt;
&lt;p&gt;python3.4에 추가된 pathlib도 아주 마음에 들어서 기존 코드들을 변경했습니다. &lt;a href=&#34;https://www.python.org/dev/peps/pep-0428/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;python&lt;/a&gt; &lt;code&gt;os.path&lt;/code&gt; 보다 좋고, 특히 아래처럼 &lt;code&gt;parent&lt;/code&gt; 같은 것을 자연스럽게 쓸 수 있다는 점이 좋습니다.&lt;/p&gt;
&lt;div class=&#34;highlighter-rouge&#34;&gt;&lt;pre class=&#34;highlight&#34;&gt;&lt;code&gt;import pathlib
pathlib.Path(&amp;#39;/home/sangwook/tmp/vim&amp;#39;).parent.parent.joinpath(&amp;#39;.vimrc&amp;#39;).exists()&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h2 id=&#34;vim&#34;&gt;vim&lt;/h2&gt;
&lt;p&gt;ale에 java를 위한 checkstyle 지원 기능이 추가되었습니다. &lt;a href=&#34;https://github.com/w0rp/ale/commit/9baae52d1afab8af832c4249eefc19e7dd28a251&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;github&lt;/a&gt; checkstyle 설정 파일을 손보다가, google의 자바 스타일 가이드는 들여쓰기가 2-spaces 라는 사실을 알게 되었습니다. &lt;a href=&#34;https://google.github.io/styleguide/javaguide.html#s4.2-block-indentation&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;github&lt;/a&gt; 디폴트 파일을 그대로 쓰려고 했는데 결국 4-spaces 로 설정을 바꿔야 했습니다. 왜 구글은 자바 표준을 따르지 않을까 싶은 마음이 들었습니다. 저는 4-spaces 를 좋아하지 않지만, 표준은 따라야 한다고 생각합니다. 아니면 이것이 표준이 아니라 &amp;ldquo;사실상 표준&amp;quot;인 것일까요? 공개된 장소에 글을 쓰려면 이런 것 하나에도 사실 여부를 확인하고 근거 링크를 달아야 하겠지만, 그런 부담을 놓기로 했기 때문에 그냥 넘어가기로 합니다.&lt;/p&gt;
&lt;p&gt;vim에서 &lt;code&gt;_spec.rb&lt;/code&gt; 같은 rspec 파일을 편집하다가, 현재 라인이 포함된 테스트만 실행하고 싶어 방법을 찾아봤습니다. 단순히 &lt;code&gt;rspec path/to/a_spec.rb:37&lt;/code&gt; 처럼 &lt;code&gt;:줄번호&lt;/code&gt; 를 붙이면 된다는 것을 확인하고 &lt;code&gt;vimrc&lt;/code&gt; 를 수정했습니다. 그 덕분에 테스트 속도가 아주 빨라졌습니다.&lt;/p&gt;
&lt;p&gt;vim을 종료하는 방법을 물어보는 stackoverflow 질문/답변 페이지가 조회수 1백만을 돌파했다고 합니다. &lt;a href=&#34;https://stackoverflow.blog/2017/05/23/stack-overflow-helping-one-million-developers-exit-vim/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;stackoverflow&lt;/a&gt; 2016년 전체 PV의 0.005% 정도이고, 평일 피크 시에는 시간당 80명 정도가 본다고 합니다.&lt;/p&gt;
&lt;p&gt;최근 vim 업데이트는 &lt;code&gt;:terminal&lt;/code&gt; 관련이 대부분입니다. &lt;a href=&#34;https://github.com/vim/vim/commit/e4f25e4a8db2c8a8a71a4ba2a68540b3ab341e42&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;github&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/assets/2017/170801-2-bcd8bb5437b460bae9797e5a2a314d5d1e6b02a2f69f7a62d9c80dce72fc269b.png&#34; alt=&#34;이미지&#34;&gt;&lt;/p&gt;
&lt;p&gt;판올림하고 직접 써 봤습니다. 신기하긴 한데 tmux가 편해서 결국 쓰지 않기로 했습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/assets/2017/170801-1-cf43c3b9490f767f17c2c4fcab6c8d8ad63c60aafc929a0eb5788994157065a3.png&#34; alt=&#34;이미지&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;kafka-hbase-rabbitmq&#34;&gt;kafka, hbase, rabbitmq&lt;/h2&gt;
&lt;p&gt;kafka, hbase, rabbitmq에 대한 성능 테스트를 했습니다. 자세히는 kafka 메시지를 소비하고, hbase에 쓰고, rabbitmq에 메시지를 생산하는 것을 하나의 트랜잭션으로 묶어, 유실 없이 초당 최대 5만 개 메시지를 처리해야 한다는 요구사항이었습니다. 유실이 없어야 하니 당연히 at-least-once 구성입니다. 이론적으로는 중복이 발생할 수 있는 구조이지만, 아주 많은 양을 오랫동안 테스트했고 몇 주간 실제 데이터로 운영도 하며 검사했는데 한 번도 발생하지 않았습니다.&lt;/p&gt;
&lt;p&gt;성능 테스트에서는 빨리 많은 테스트 데이터를 생성하는 것이 핵심인 것 같습니다. 변수를 바꿔 가며 많은 실험을 해야 하기 때문입니다. 저에게 익숙한 것이 ruby이니 ruby-kafka 를 사용했습니다. &lt;a href=&#34;https://github.com/zendesk/ruby-kafka#efficiently-producing-messages&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;github&lt;/a&gt; 스레드 수와 flush 하는 버퍼의 크기를 조정해 가며 초당 20_000 개 정도를 produce 했습니다. 그런데 kafka에 느리게라도 produce 해 두고 offset을 earliest 로 가져오면 매번 테스트 데이터를 새로 만들 필요가 없다는 사실을, 회사에서 eric이 알려 주었습니다. 저는 왜 일찍 그 생각을 하지 못했을까 싶었습니다.&lt;/p&gt;
&lt;p&gt;이 작업을 하면서 hbase에 대해서도, kafka에 대해서도 배운 것이 많은데, 언젠가 글로 정리할 날이 있겠지 싶습니다.&lt;/p&gt;
&lt;h2 id=&#34;기타&#34;&gt;기타&lt;/h2&gt;
&lt;p&gt;덩케르크를 봤습니다. 재미있게 봤습니다. 전쟁에 진정한 승자가 있을까, 결국 남는 것은 과부와 고아가 아닐까 하는 생각을 다시 한번 했습니다.&lt;/p&gt;
&lt;p&gt;프로세스와 규칙이 많아질수록 안정성은 늘어나지만, 그만큼 혁신의 여지는 줄어드는 면이 있다고 봅니다. 촘촘한 규칙이 균일한 맛의 맥도날드 햄버거를 보장할 수는 있을 것입니다. 하지만 맥도날드에서 일하는 사람은 자신을 요리사라고 생각하지 않습니다. 좋은 요리사는 맥도날드로 모이지 않습니다.&lt;/p&gt;
&lt;p&gt;telegram API를 써서 개인적인 메시지를 받고 있는데, 정말 좋습니다. 제가 필요한 것 이상의 모든 것이 구현되어 있고, bot을 만드는 것도 쉽습니다. 아주 만족하고 있습니다. 마크다운 형식으로 메시지를 보낼 수 있고 고정폭 글꼴로 표시되게 만들 수도 있다는 사실을 발견한 뒤로 더 좋아하게 되었습니다.&lt;/p&gt;
&lt;p&gt;SNS에서 정적 기록자(static logger) 관련 토론을 봤습니다. &lt;a href=&#34;https://justhackem.wordpress.com/2017/07/07/no-more-static-logger/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;wordpress&lt;/a&gt; &lt;a href=&#34;https://www.facebook.com/tobyilee/posts/10210853744514228&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;facebook&lt;/a&gt; logger를 static으로 했을 때의 단점, 또는 static으로 하지 않을 때의 장점(생성자에 logger를 넘기는 방식 같은 것)을 각각 샘플 코드를 통해 보여 주시면 읽기 좋을 텐데, 하는 생각이 들었습니다. 하지만 이런들 어떠하고 저런들 어떠하리. 저에게는 그리 중요한 관심사가 아니라서 지나가기로 합니다.&lt;/p&gt;
&lt;p&gt;박성철님의 글도 잘 읽었습니다. &lt;a href=&#34;https://www.facebook.com/fupfin.geek/posts/601525090236478&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;facebook&lt;/a&gt; 공감하는 부분이 많았습니다. 싸고 좋은 사람을 채용하려는 노력이 회사에 이익이라고 생각하기 쉬운데, 실제로는 더 많은 규칙, 더 많은 프로세스, 그리고 문제를 조금 덜 발생시키는 기술을 고민하는 쪽으로 이어지는 경우가 적지 않은 듯합니다.&lt;/p&gt;
&lt;p&gt;책을 모두 버렸습니다. 정확히는 회사 도서관에 기증했습니다. 다시는 책을 사지 말아야겠다고 생각했습니다. 몇 년 전부터 컨퍼런스는 가지 말아야겠다고 생각한 것과 비슷한 마음입니다.&lt;/p&gt;
&lt;p&gt;회사에서 대략 2년 x개월 만에 다시 mesos, marathon, 컨테이너 같은 클라우드 컴퓨팅 인프라를 개발하는 부서로 돌아왔습니다.&lt;/p&gt;
</content>
<author><name></name></author>
<summary type="html">kubernetes https://github.com 이 kubernetes 위에서 100% 돌아가도록 이전했다고 합니다. githubengineering 정확히는 rails 웹앱을 모두 kubernetes 클러스터의 컨테이너에 올렸다는 이야기입니다. 일단 kubernetes 성공 사례라서 반가웠고, 추상적인 이야기가 아니라 실용적인 내용이 많아서 더 좋았 …</summary>
</entry>
<entry>
<title type="html">2017년 Rails, JavaScript에 대한 DHH의 생각</title>
<link href="https://sangwook.github.io/2017/02/21/ruby-dhh-javascript-rails-redux.html" rel="alternate" type="text/html" title="2017년 Rails, JavaScript에 대한 DHH의 생각" />
<published>2017-02-21T21:51:00+09:00</published>
<updated>2017-02-21T21:51:00+09:00</updated>
<id>https://sangwook.github.io/2017/02/21/ruby-dhh-javascript-rails-redux</id>
<content type="html" xml:base="https://sangwook.github.io/2017/02/21/ruby-dhh-javascript-rails-redux.html">&lt;p&gt;&lt;img src=&#34;/assets/2017/170221-1-f052746c2682481166b401cc114c3579db315f87be47ec17c73e58fb61a748f3.jpg&#34; alt=&#34;이미지&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;dhh의-생각을-읽은-후-내-생각&#34;&gt;DHH의 생각(을 읽은 후 내 생각)&lt;/h2&gt;
&lt;p&gt;Rails를 만든 것으로 유명한 DHH님이 Quora에서 질문을 받는 세션을 가졌습니다. &lt;a href=&#34;https://www.quora.com/session/David-Heinemeier-Hansson/1&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;quora&lt;/a&gt; 재미있는 질문이 많았습니다. 예를 들어 &amp;ldquo;2017년에 Rails 프레임워크를 배울 가치가 뭐야?&amp;rdquo;, &amp;ldquo;JavaScript 프레임워크가 Rails를 먹게 될까?&amp;rdquo;, &amp;ldquo;왜 Python이 아니라 Ruby로 Rails를 만들었니?&amp;rdquo; 같은 질문들입니다. 질문만 봐도 읽고 싶어집니다. 게다가 DHH님은 글을 잘 씁니다. 전부 읽고 나니 제 생각과 비슷하다고 느꼈습니다. 오래전부터 제가 DHH님에게 영향을 많이 받았다는 증거일 것입니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;While we’ve seen a lot a progress in the JavaScript world, we’ve also seen a regression to the complexity-laden world that Rails offered refuge from in the early days.
Back then the complexity merchant of choice was J2EE, but the complaints are uncannily similar to those leveled against JavaScript today.
That people spent hours, if not days, just setting up the skeletons.
The basic build configurations.
Assembling and cherry-picking from lots of little libraries and frameworks to put together their own snowflake house variety.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;13년 전 J2EE와 비교할 정도로 지금의 JavaScript world를 복잡하다고 DHH님은 보고 있습니다. 저 역시 현재 JavaScript world에서 만들어지는 것들을 좋아하지 않습니다. 스프레드시트 정도의 SPA를 만들어야 한다면 redux 같은 것은 어쩔 수 없는 선택지입니다. 하지만 선택하기 전에, 오버엔지니어링이 아닌지 일단 의심해 봐야 합니다. 오버엔지니어링과 이른 최적화는 모든 악의 근원입니다. JavaScript world는 앞으로도 크게 변할 것입니다. 아마 몇 년 뒤에는 지금과 많이 달라질 것이고, 그때는 저도 생각이 달라질 수 있겠습니다. hibernate를 처음 봤을 때의 생각과 지금의 생각이 다른 것처럼 말입니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;That by formalizing conventions, eliminating valueless choices, and offering a full-stack framework that provides great defaults for anyone who wants to create a complete application, we can make dramatic strides of productivity.
&amp;hellip;
The vast majority of activity today is for yet another option on the a la carte menu. Yet another build system, yet another view library, yet another ORM. Very little activity in integrated solutions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Rails는 full-stack framework를 목표로 합니다. conventions를 formalizing 하고, 가치 없는 선택지를 제거하고, 디폴트를 제공하는 식으로 높은 생산성을 만들어 냅니다. 즉, Rails는 integrated solutions 를 지향합니다. 이런 목표를 일관되게 추구하는 프레임워크 중에서는 Rails가 꽤 두드러진 사례라고 봅니다. Rails 외에는 또 다른 option, 또 다른 빌드 시스템, 또 다른 view library, 또 다른 ORM을 내놓는 방향이 많아 보입니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You get to use Ruby, which, even in a world that has rediscovered the benefits of functional programming and immutability, remains the most extraordinarily beautiful and luxurious language I’ve yet to encounter.
Just look at some code.
I dare you not to fall in love.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ruby는 함수형 언어의 장점이 재발견된 이 시대에 와서도 DHH님이 본 언어 중 가장 아름다운 언어라고 합니다. 동의합니다. 사실 제가 python과 ruby 사이에서 ruby를 선택했던 이유는 처음엔 단순했습니다. string interpolation이 ruby에서는 되고 python에서는 안 되는 점이 가장 컸습니다. &lt;a href=&#34;https://en.wikipedia.org/wiki/String_interpolation#Ruby_.2F_Crystal&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;wikipedia&lt;/a&gt; 최근 python3.6 부터 python도 가능해졌습니다. &lt;a href=&#34;https://www.python.org/dev/peps/pep-0498/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;python&lt;/a&gt; 다만 앞에 &lt;code&gt;f&lt;/code&gt; 를 붙이는 것을 보니, 역시 python과 ruby는 지향하는 길이 다른 것 같습니다. 그리고 저는 4-spaces 보다 2-spaces가 좋습니다. 사소한 이유지요. python 코드도 가끔 읽을 때가 있는데, 매일 python을 쓰지 않는 저에게 python의 list comprehensions는 좀처럼 익숙해지지 않습니다. 예를 들어 &lt;code&gt;[x**2 for x in range(10)]&lt;/code&gt; 같은 것입니다. 그보다는 ruby의 블록이 저에게는 훨씬 쉽고, 생각의 속도로 코딩이 가능하며 읽기에도 자연스럽습니다. 같은 일을 ruby로 적으면 &lt;code&gt;(0..9).map{|x|x**2}&lt;/code&gt; 가 됩니다.&lt;/p&gt;
&lt;h2 id=&#34;ruby-24&#34;&gt;Ruby 2.4&lt;/h2&gt;
&lt;p&gt;지난 크리스마스(2016-12-25)에, ruby2.3 이후 1년 만에 ruby2.4가 나왔습니다. &lt;a href=&#34;https://www.ruby-lang.org/en/news/2016/12/25/ruby-2-4-0-released/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;ruby-lang&lt;/a&gt; &lt;a href=&#34;http://nithinbekal.com/posts/ruby-2-4-features/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;nithinbekal&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;반올림 함수(&lt;code&gt;Float#round&lt;/code&gt;)의 디폴트 동작이 even-half가 되는 무시무시한 이야기가 있었습니다. 실제로 preview3 까지는 &lt;code&gt;2.5.round&lt;/code&gt; 의 결과가 &lt;code&gt;2&lt;/code&gt; 였습니다. 많은 논란 끝에 결과적으로는 even-half로 동작하는 옵션이 추가되는 것으로 마무리되었습니다. even-half 옵션을 제가 쓸 일이 있을지 잘 모르겠습니다.&lt;/p&gt;
&lt;p&gt;rails의 ActiveSupport에 있던 &lt;code&gt;Hash#transform_values&lt;/code&gt; 가 core에 포함되었습니다.&lt;/p&gt;
&lt;p&gt;pry의 &lt;code&gt;binding.pry&lt;/code&gt; 와 동일한 기능이 irb에도 &lt;code&gt;binding.irb&lt;/code&gt; 로 추가되었다고 합니다. 다만 pry 대신 irb를 쓸 이유는 딱히 없어 보입니다.&lt;/p&gt;
&lt;p&gt;true/false만 리턴하는 &lt;code&gt;Regexp#match?&lt;/code&gt; 가 추가되었습니다. &lt;code&gt;Regexp#match&lt;/code&gt; 보다 당연히 빠르다고 합니다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;MatchData#named_captures&lt;/code&gt; 도 추가되었습니다. 아래처럼 이름 있는 captures를 Hash로 리턴해 주는 메소드라서 아주 편할 것 같습니다.&lt;/p&gt;
&lt;div class=&#34;highlighter-rouge&#34;&gt;&lt;pre class=&#34;highlight&#34;&gt;&lt;code&gt;/(?&amp;lt;fname&amp;gt;.&amp;#43;) (?&amp;lt;lname&amp;gt;.&amp;#43;)/.match(&amp;#39;Ned Stark&amp;#39;).named_captures
#=&amp;gt; {&amp;#34;fname&amp;#34;=&amp;gt;&amp;#34;Ned&amp;#34;, &amp;#34;lname&amp;#34;=&amp;gt;&amp;#34;Stark&amp;#34;}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</content>
<author><name></name></author>
<summary type="html">
DHH의 생각(을 읽은 후 내 생각) Rails를 만든 것으로 유명한 DHH님이 Quora에서 질문을 받는 세션을 가졌습니다. quora 재미있는 질문이 많았습니다. 예를 들어 &amp;ldquo;2017년에 Rails 프레임워크를 배울 가치가 뭐야?&amp;rdquo;, &amp;ldquo;JavaScript 프레임워크가 Rails를 먹게 될까?&amp;rdquo;, &amp;ldquo; …</summary>
</entry>
<entry>
<title type="html">Uber의 Message Queue, Akka, Vim, Java</title>
<link href="https://sangwook.github.io/2016/12/14/uber-message-queue-akka-vim-java.html" rel="alternate" type="text/html" title="Uber의 Message Queue, Akka, Vim, Java" />
<published>2016-12-14T21:59:00+09:00</published>
<updated>2016-12-14T21:59:00+09:00</updated>
<id>https://sangwook.github.io/2016/12/14/uber-message-queue-akka-vim-java</id>
<content type="html" xml:base="https://sangwook.github.io/2016/12/14/uber-message-queue-akka-vim-java.html">&lt;h3 id=&#34;uber가-만든-mq-디자인-task-queue-용도&#34;&gt;Uber가 만든 MQ 디자인. (task-queue 용도)&lt;/h3&gt;
&lt;p&gt;Uber가 며칠 전(12/6)에 &amp;ldquo;Cherami: Uber Engineering’s Durable and Scalable Task Queue in Go - Uber Engineering Blog&amp;quot;라는 제목으로 글을 올렸습니다. &lt;a href=&#34;https://eng.uber.com/cherami/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://eng.uber.com/cherami/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Uber는 microservice-architecture(이하 MSA)로 운영하는 것으로 유명합니다. 이 글로 MSA에 필수인 큐를 Uber가 어떤 디자인으로 만들었는지 알 수 있고, 그 디자인이 실제로 어떻게 구현되며 어떤 고민을 안고 있는지도 엿볼 수 있습니다. 남이 만든 디자인을 관찰하는 일은 재미있습니다. 저는 주로 가용성과 확장성을 봅니다. 저에게 처리량은 확장성에 포함되고, fault-tolerance는 가용성에 포함됩니다. 엄격히 말하면 다른 개념이지만, 저는 그렇게 묶어 둡니다. Uber는 하루에 1억 개의 메시지가 오간다고 하니, 단순히 계산하면 초당 평균 1,157개 정도의 메시지로 추정할 수 있습니다. Uber에서 이 메시지가 사용되는 사례로 밝힌 것은 post-trip processing, fraud detection, user notification, incentive campaigns 같은 것들입니다.&lt;/p&gt;
&lt;p&gt;주요 디자인 선택을 보면, 가용성을 위한 선택으로 competing consumers, replicating messages, eventual consistency가 있습니다. eventual consistency를 택한 것은 아마도 순서를 보장하지 않는다는 뜻일 것입니다. 확장성을 위한 선택으로는 competing consumers가 있고, write 처리량을 관찰하다가 확장하는 역할까지 미들웨어에서 하는 것으로 보입니다.&lt;/p&gt;
&lt;p&gt;저는 새로운 솔루션을 도입하는 일에는 보수적입니다. 새로운 솔루션을 선택하는 일에는 많은 단점이 따르기 때문입니다(논증은 생략합니다). 저는 보통 둘 중 한 가지 길을 선호합니다. 하나는 새로운 솔루션의 &amp;ldquo;디자인&amp;quot;만 이해하고, 기존 기술로 요구사항에 맞춰 직접 구현하는 길입니다. 다른 하나는 그 솔루션을 아주 깊이 이해했고 동시에 전파하기도 쉬운 솔루션일 때에 한해 도입하는 길입니다. 보통은 디자인을 제대로 이해하지 못한 채 유행을 좇아 도입하는 경우가 많습니다.&lt;/p&gt;
&lt;p&gt;그중에서도 큐 시스템은 장단점이 다양한 솔루션이 많습니다. 회사마다, 팀마다 저마다의 큐를 만드는 경향도 있습니다. 고가용성과 고확장성을 갖추고 보장 옵션을 선택할 수 있는 큐가 있다면 좋겠다고 생각합니다. 지금까지는 Amazon SQS가 그것에 가장 가까웠습니다.&lt;/p&gt;
&lt;h3 id=&#34;akka&#34;&gt;Akka&lt;/h3&gt;
&lt;p&gt;최근에 Akka와 Actor model의 디자인도 잠깐 검토할 일이 있었습니다. Akka는 해 주는 일이 거의 없는 틀이었습니다. 저는 이런 프레임워크를 좋아합니다.&lt;/p&gt;
&lt;p&gt;보통은 X를 보장하면 Y가 떨어집니다. 풍선을 누르면 다른 부분이 부풀어 오르는 것과 같습니다. 세상의 일은 대부분 tradeoff입니다. 어떤 프레임워크가 X를 보장한다고 주장해도, 사실은 그 보장의 경계를 증명하기 위해 많은 비용을 써야 합니다. Akka는 오버헤드가 없는 틀만 두고 대부분의 일은 개발자에게 위임합니다. 그리고 actor model이 구조적으로 살을 붙이기 좋아 보였습니다.&lt;/p&gt;
&lt;h3 id=&#34;vim&#34;&gt;vim&lt;/h3&gt;
&lt;p&gt;vim 관련 링크를 모아 둡니다.&lt;/p&gt;
&lt;p&gt;2016 NYC Vim talk에서 &amp;ldquo;vim 플러그인이 하는 일의 90%를 플러그인 없이 하는 방법&amp;quot;이라는 제목의 발표가 있었습니다. 영상은 &lt;a href=&#34;https://www.youtube.com/watch?v=XA2WjJbmmoM&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;youtube&lt;/a&gt;, 슬라이드는 &lt;a href=&#34;https://github.com/mcantor/no_plugins/blob/master/no_plugins.vim&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;github&lt;/a&gt;에 있습니다. 재미있게 보긴 했지만 남은 것은 별로 없었습니다. 다른 내용은 좀 억지스럽고 부자연스럽게 문제를 해결하려는 것처럼 보였습니다. 플러그인으로 하면 쉬운데 왜 이렇게까지 하나 싶은 기분이 들기도 했습니다. 파일 브라우저는 저도 NERDTree보다 netrw 계열을 쓰는 데 동의합니다. 다만 NERDTree도 여전히 같이 쓰고 있습니다. 내장된 순수 netrw는 문제가 좀 있습니다.&lt;/p&gt;
&lt;p&gt;vim 스크립트 치트시트도 봤습니다. &lt;a href=&#34;http://ricostacruz.com/cheatsheets/vimscript.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;ricostacruz&lt;/a&gt; 스니펫으로 저장해 두고 쓰기 좋습니다.&lt;/p&gt;
&lt;p&gt;파이콘2016에서 vim과 gnome-desktop을 사용하시는 분이 있었습니다. &lt;a href=&#34;https://www.youtube.com/watch?v=xDz8WVO_wjE&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;youtube&lt;/a&gt; Ruby의 byebug 같은 역할을 Python에서는 pudb로 하는 듯합니다. gdb와 매핑되는 네이밍으로 보입니다. 그런데 저렇게 UI까지 제공하는 것이 좋은 선택일까 하는 생각이 들었습니다. nautilus를 터미널에서 직접 입력하시는 모습을 보고 오래된 gnome-desktop 사용자분이시구나 하는 생각이 들었습니다. vim에서 Python 자동완성을 위해 &lt;a href=&#34;https://github.com/davidhalter/jedi-vim&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;jedi-vim&lt;/a&gt;을 사용하신다고 합니다.&lt;/p&gt;
&lt;p&gt;redis를 만든 antirez님이 vim을 어떻게 쓰는지 쓴 글도 읽었습니다. &lt;a href=&#34;http://howivim.com/2016/salvatore-sanfilippo/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;howivim&lt;/a&gt; antirez님이 쓰는 전체 vimrc는 이것인 듯합니다. &lt;a href=&#34;https://gist.github.com/antirez/3860461&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;github&lt;/a&gt; 특별한 것은 없고 vim을 최소한의 설정으로 가볍게 쓰시는 스타일입니다. 실수 방지를 위해 &lt;code&gt;map 4 $&lt;/code&gt;를 설정해 두신 점이 귀엽습니다. 저도 따라 설정해 봤는데, 너무 불편해서 며칠 만에 그만뒀습니다. &lt;code&gt;r!date&lt;/code&gt;는 저도 설정해서 쓰는데, 같은 사람을 또 만났다는 사실이 반가웠습니다.&lt;/p&gt;
&lt;h3 id=&#34;java&#34;&gt;java&lt;/h3&gt;
&lt;p&gt;Java 생태계는 unix 철학을 따르지 않고, 제가 쓰기에는 불편한 점이 많습니다. 저랑은 정말 안 맞는 것 같습니다.&lt;/p&gt;
&lt;p&gt;예를 들어 현재 프로젝트의 dependency 목록을 보여주는 shell 함수를 만들고 싶었습니다. 당연히 &lt;code&gt;mvn help:effective-pom | xml2json | jq &#39;...생략...&#39;&lt;/code&gt; 정도로 간단히 되겠지 싶었지만, &lt;code&gt;mvn help:effective-pom&lt;/code&gt; 결과는 XML 외에도 info log 정보를 verbose하게 stdout에 같이 뿌립니다. XML만 출력하려면 파일로 쓰고 그 파일을 다시 읽어 작업해야 합니다. 불편합니다. verbose 옵션이 디폴트라니. quiet 옵션도 없습니다.&lt;/p&gt;
&lt;p&gt;원격 의존성을 shell에서 검색하고 싶기도 했습니다. Ruby라면 &lt;code&gt;gem search kafka&lt;/code&gt;, Python이라면 &lt;code&gt;pip search kafka&lt;/code&gt;, Docker라면 &lt;code&gt;docker search kafka&lt;/code&gt;, apt라면 &lt;code&gt;apt search kafka&lt;/code&gt;를 할 텐데, Java에서는 도대체 왜 &lt;code&gt;mvn search kafka&lt;/code&gt; 같은 명령이 없는지 모르겠습니다. 다행히 &lt;code&gt;mvn-search kafka&lt;/code&gt; 식으로 만들 수 있도록 누군가 savant &lt;a href=&#34;https://github.com/spilth/savant&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;github&lt;/a&gt;라는 도구를 만들어 두었습니다(덧붙이자면, Ruby의 kafka 라이브러리가 옛날 버전만 지원하는 것을 보고 좀 우울해졌습니다).&lt;/p&gt;
&lt;p&gt;모든 의존성의 문자열 검색을 ag 같은 외부 툴로 하고 싶기도 했습니다. Ruby라면 &lt;code&gt;ag ~/.rvm/gems/ruby-2.3.1/gems/&lt;/code&gt;로 검색하면 됩니다. 실제로 저는 이런 검색을 하는 vim 커맨드를 만들어 키 하나로 찾아갑니다. Java에서도 같은 일을 해 볼까 해서 시도해 봤는데, 일단 Maven Repository에 소스를 올리지 않는 라이브러리가 많습니다. 그리고 모두 jar로 압축된 형태로 &lt;code&gt;~/.m2/repository&lt;/code&gt; 아래에 저장됩니다. ag로 검색하려면 jar를 풀고 class를 디컴파일해서 저장해야 합니다. 악. 안 합니다, 안 해.&lt;/p&gt;
&lt;p&gt;Java에도 타입 추론이 제안되었습니다. &lt;a href=&#34;http://openjdk.java.net/jeps/286&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;java&lt;/a&gt; Java 커뮤니티는 세계 최고로 보수적인 프로그래머 집단이라서, Scala나 Kotlin의 기능들을 아주 천천히 흡수하고 있습니다. NeoVim의 핵심 기능을 Vim8이 따라잡는 흐름이나, CoffeeScript 같은 언어가 결국 본진에 흡수되며 입지가 줄어드는 흐름과 비슷해 보입니다. Kotlin 같은 언어도 (너무!) 좋지만 결국 비슷한 길을 걷지 않을까 짐작해 봅니다.&lt;/p&gt;
&lt;p&gt;타입 추론의 문법은 다음 중 하나로 결정될 것 같습니다. &lt;code&gt;var x = expr&lt;/code&gt; only (like C#), &lt;code&gt;var, plus val for immutable locals&lt;/code&gt; (like Scala, Kotlin), &lt;code&gt;var, plus let for immutable locals&lt;/code&gt; (like Swift), &lt;code&gt;auto x = expr&lt;/code&gt; (like C++), &lt;code&gt;const x = expr&lt;/code&gt; (already a reserved word), &lt;code&gt;final x = expr&lt;/code&gt; (already a reserved word), &lt;code&gt;let x = expr&lt;/code&gt;, &lt;code&gt;def x = expr&lt;/code&gt; (like Groovy), &lt;code&gt;x := expr&lt;/code&gt; (like Go).&lt;/p&gt;
&lt;p&gt;저는 Go 스타일의 &lt;code&gt;x := expr&lt;/code&gt;로 결정되면 좋겠는데, 자바스럽지 않다며 기각되었다고 합니다. &amp;ldquo;The Go syntax (a different kind of assignment operator) seems pretty un-Javaish.&amp;rdquo; 자바스럽지 않다니, 하.&lt;/p&gt;
</content>
<author><name></name></author>
<summary type="html">Uber가 만든 MQ 디자인. (task-queue 용도) Uber가 며칠 전(12/6)에 &amp;ldquo;Cherami: Uber Engineering’s Durable and Scalable Task Queue in Go - Uber Engineering Blog&amp;quot;라는 제목으로 글을 올렸습니다. https://eng.uber.com/cherami/ …</summary>
</entry>
<entry>
<title type="html">우분투16과 KDE</title>
<link href="https://sangwook.github.io/2016/10/11/ubuntu-1604-kde.html" rel="alternate" type="text/html" title="우분투16과 KDE" />
<published>2016-10-11T21:36:00+09:00</published>
<updated>2016-10-11T21:36:00+09:00</updated>
<id>https://sangwook.github.io/2016/10/11/ubuntu-1604-kde</id>
<content type="html" xml:base="https://sangwook.github.io/2016/10/11/ubuntu-1604-kde.html">&lt;p&gt;&lt;img src=&#34;/assets/2016/161011-ubuntu16-screenfetch-d309a0fce49f7abaf5a95f61a72481466e2187b8b361c52f334b03de5a55c92d.jpg&#34; alt=&#34;이미지&#34;&gt;&lt;/p&gt;
&lt;p&gt;오랫동안 Ubuntu 14.04 LTS를 써 왔습니다. Unity는 불편했지만 그럭저럭 적응하며 익숙해졌습니다. 그래도 다음 OS에서는 Unity를 쓰지 말자고 다짐했습니다. 왜냐고 물으면 명확하게 답을 못 하겠습니다. 살짝 느린 느낌이 든다는, 제가 싫어하는 비과학적인 답을 해야 합니다. 아무튼 다음에는 archlinux나 debian처럼 rolling update가 가능한 OS를 쓰고 싶었습니다.&lt;/p&gt;
&lt;p&gt;처음에는 archlinux 기반에 tiling WM을 검토했습니다. 다른 HDD 파티션에 archlinux를 깔고 WM으로 i3wm을 설치했습니다. i3wm을 고른 이유는 가장 많이 쓰이는 WM이기 때문입니다. &lt;a href=&#34;http://pollmill.com/f/which-tiling-window-manager-do-you-use-dax6md8/answers&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;pollmill&lt;/a&gt; &lt;a href=&#34;https://www.reddit.com/r/archlinux/comments/2t7cek/poll_which_tiling_window_manager_do_you_use/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;reddit&lt;/a&gt; &lt;a href=&#34;https://www.slant.co/topics/390/~window-managers-for-linux&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;slant&lt;/a&gt; 결과적으로 i3wm은 사용을 포기했습니다. 문제가 꽤 많았고 하나씩 해결해 가긴 했지만, 아래 두 가지에서 시간을 너무 쓰는 것 같아 현재는 미뤄 둔 상태입니다. 첫째, wine 기반으로 KakaoTalk을 설치하면 tiling이 제대로 동작하지 않았습니다. wine만 예외로 tiling을 disable해도 여전히 이상하게 동작했습니다. 둘째, Chrome이 느렸습니다. 정확히는 URL 입력 바에서 키 입력에 지연이 있었고, 탭 이동이나 페이지 로딩에서도 약간씩 지연이 있었습니다. 아마도 Ubuntu 패키지가 자동으로 잡아 주던 그래픽 드라이버 설정을 i3wm에서는 수동으로 해 줘야 하는 게 아닐까 추측하고 있습니다.&lt;/p&gt;
&lt;p&gt;2016년 3월 13일, 알파고와 이세돌의 경기를 매일 재미있게 보다가 발견한 사실이 있습니다. 알파고는 Ubuntu14, Unity에서 돌아가는 것으로 보였습니다. 근거는 다음과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/assets/2016/161011-ubuntu16-alphago-1-246ac004e646202179647c76eca6eb822b1eb4f587317e24d41273e2ace24d04.jpg&#34; alt=&#34;이미지&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/assets/2016/161011-ubuntu16-alphago-2-283ceb53b9d506f21b0e87fe68ec3641035dca8ad81e19babd9c38e35fb01e97.jpg&#34; alt=&#34;이미지&#34;&gt;&lt;/p&gt;
&lt;p&gt;2016년 4월 21일에 Ubuntu 16.04가 릴리즈되었습니다. &lt;a href=&#34;https://www.reddit.com/r/linux/comments/4ftq8e/ubuntu_1604_lts_has_been_officially_released/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;reddit&lt;/a&gt; &lt;a href=&#34;https://www.reddit.com/r/Ubuntu/comments/4ftqs0/ubuntu_1604_lts_has_been_released/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;reddit&lt;/a&gt; 바로 업그레이드를 하려고 했지만 일이 바빠서 미뤘습니다. 역시 LTS는 16.04.1이 나오고 나서 업그레이드해야 마음이 놓입니다. 그러고는 2016년 7월 22일에 Ubuntu 16.04.1이 릴리즈되었습니다. &lt;a href=&#34;https://www.reddit.com/r/linux/comments/4txzoa/ubuntu_16041_lts_released/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;reddit&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;회사에서 KDE를 좋아하는 쿠퍼님에게 설득되어 KDE를 써 보기로 했습니다. KDE의 가장 큰 장점은 파일 관리자인 Dolphin이 매우 좋다는 점입니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/assets/2016/161011-ubuntu16-dolphin-dd3bf87733960876295ec4425d8a0e035cf863f64f47fad9d36ba0c250f002d3.jpg&#34; alt=&#34;이미지&#34;&gt;&lt;/p&gt;
&lt;p&gt;저는 원래 shell에서 파일 관리를 주로 하는 편이라, Ubuntu14에서 쓰던 GNOME Files(=Nautilus)에도 딱히 불만이 없었습니다. 그런데 Dolphin을 몇 주 써 보니 아주 만족스럽습니다. split이 된다는 점, 아래쪽에 shell이 함께 나온다는 점, 디렉터리를 옮기면 그 아래의 shell도 자동으로 cd가 된다는 점이 마음에 듭니다. 적어도 제 취향에는 macOS의 Finder보다 훨씬 잘 맞습니다. 여러 파일을 한 번에 rename할 때 혹시 regex를 지원할까 기대했지만 그건 안 됩니다. 이건 shell에서 하면 되니 큰 문제는 아닙니다.&lt;/p&gt;
&lt;p&gt;다른 HDD 파티션에 Kubuntu 16.04.1을 설치했습니다. USB로 부팅하기 위해 &lt;code&gt;sudo dd if=./kubuntu-16.04.1-desktop-amd64.iso of=/dev/sdb&lt;/code&gt;를 했고, GRUB이 뜬 다음 start kubuntu에서 install kubuntu로 설치를 진행했습니다. &lt;a href=&#34;http://sangwook.github.io/images/2016/161011-ubuntu16-grub.jpg&#34;&gt;&lt;img src=&#34;http://sangwook.github.io/images/2016/161011-ubuntu16-grub.jpg&#34; alt=&#34;GRUB&#34;&gt;&lt;/a&gt; 네트워크를 잡고 git, curl, tmux, zsh, vim, dropbox, fcitx를 설치했습니다. system ruby, python, nodejs를 그대로 쓰지 않으려고 rvm, pyenv, nvm을 설치했습니다. system ruby와 python을 못 쓰게 하려고 &lt;code&gt;/usr/bin/python*&lt;/code&gt;을 rename했더니, 이번엔 terminator가 실행되며 오류를 내서 다시 되돌렸습니다. wine과 KakaoTalk도 설치했습니다. 여기까지 깔린 상태가 제 필수 환경이라고 생각합니다.&lt;/p&gt;
&lt;p&gt;Ubuntu14를 메인으로 계속 쓰면서 하루에 10분에서 30분씩 Kubuntu16으로 부팅해 문제를 만나고 해결하기를 반복했습니다. 3개월 정도의 트러블슈팅 끝에 드디어 Kubuntu16을 메인으로 쓰기 시작했습니다.&lt;/p&gt;
&lt;h3 id=&#34;ubuntu14-unity-에서---ubuntu16-kde-로-넘어오면서-생긴-문제해결&#34;&gt;Ubuntu14 Unity 에서 -&amp;gt; Ubuntu16 KDE 로 넘어오면서 생긴 문제/해결&lt;/h3&gt;
&lt;p&gt;부팅했을 때 fcitx가 자동으로 실행되지 않는 문제가 있었습니다. &lt;code&gt;~/.config/autostart/fcitx-autostart.desktop&lt;/code&gt; 파일을 만들어 해결했습니다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;zshrc&lt;/code&gt; 안에서 DE가 KDE인지 여부에 따라 분기하는 로직이 필요했습니다. &lt;code&gt;$DESKTOP_SESSION&lt;/code&gt;을 쓸까 고민하다가 &lt;code&gt;$XDG_CURRENT_DESKTOP&lt;/code&gt;을 쓰기로 했습니다.&lt;/p&gt;
&lt;p&gt;KDE가 &lt;code&gt;~/.xprofile&lt;/code&gt;을 읽지 않는 문제가 있었습니다. &lt;code&gt;/etc/X11/Xsession.d/&lt;/code&gt; 아래에 파일을 생성해서 해결했습니다.&lt;/p&gt;
&lt;p&gt;나눔고딕코딩 글꼴 설치가 잘 되지 않았습니다. &lt;a href=&#34;http://dev.naver.com/projects/nanumfont/wiki/Install&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;공식 사이트의 설치 가이드&lt;/a&gt;대로 하면 오류가 났습니다. &lt;code&gt;sudo apt install fonts-nanum fonts-nanum-extra fonts-nanum-coding fonts-baekmuk fonts-unfonts-core fonts-unfonts-extra&lt;/code&gt;로 패키지를 깔아 해결했습니다.&lt;/p&gt;
&lt;p&gt;KDE 기본 터미널인 konsole에서 NanumGothicCoding 폰트를 선택할 수 없었습니다. 결국 konsole 대신 다른 터미널을 쓰기로 했습니다. 처음에는 top-down terminal을 시도했습니다. top-down terminal이란 게임 Quake의 채팅창처럼 F12를 누르면 위에서 터미널이 내려오는 스타일을 말합니다. Guake, Yakuake, Tilda 같은 것들이 여기에 속합니다. 여기서도 설정 문제가 있어서, 결국 terminator에 적응했습니다.&lt;/p&gt;
&lt;p&gt;app launcher를 meta 키 하나로 실행하고 싶었습니다. KDE의 설정 어디에도 mod 키 하나만으로는 shortcut을 지정할 수 없었습니다. 어쩔 수 없이 meta+z로 shortcut을 잡았습니다.&lt;/p&gt;
&lt;p&gt;특정 키를 누르면 특정 앱이 실행되거나 해당 앱으로 포커스가 옮겨 가는 shortcut을 만들고 싶었습니다. KDE는 명령을 global shortcut으로 잡을 수 있고, 다음과 같이 포커스를 옮기거나 실행할 수 있습니다.&lt;/p&gt;
&lt;div class=&#34;highlighter-rouge&#34;&gt;&lt;pre class=&#34;highlight&#34;&gt;&lt;code&gt;wmctrl -xa terminator.Terminator || terminator&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;&lt;a href=&#34;http://sangwook.github.io/images/2016/161011-ubuntu16-shortcut-wmctrl.jpg&#34;&gt;&lt;img src=&#34;http://sangwook.github.io/images/2016/161011-ubuntu16-shortcut-wmctrl.jpg&#34; alt=&#34;shortcut&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;R_ALT를 한/영 키로 설정했더니 빠르게 한영 전환이 되지 않는 문제가 있었습니다. right alt만 전체적으로 disable하고 싶었지만 그건 불가능한 것 같았습니다. 사용하지 않는 ALT 조합 shortcut을 보이는 대로 지웠습니다.&lt;/p&gt;
&lt;p&gt;proxy 설정을 shell에서 하고 싶었습니다. Ubuntu14 Unity에서는 &lt;code&gt;gsettings&lt;/code&gt; 명령으로 설정했었습니다. KDE에서는 아래 파일과 명령으로 가능해 보이는데, 일단 필요할 때 적용하는 것으로 미뤄 두었습니다.&lt;/p&gt;
&lt;div class=&#34;highlighter-rouge&#34;&gt;&lt;pre class=&#34;highlight&#34;&gt;&lt;code&gt;~/.kde/share/config/kioslaverc
kreadconfig --file kioslaverc --group &amp;#34;Proxy Settings&amp;#34; --key httpproxy&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;vim을 소스에서 직접 빌드하는 데 문제가 있었습니다. &lt;code&gt;--enable-gui=auto&lt;/code&gt; 옵션으로 빌드하면 &lt;code&gt;checking --enable-gui argument... no GUI support&lt;/code&gt;라는 에러가 났습니다. &lt;code&gt;/etc/apt/sources.list&lt;/code&gt;가 디폴트로 &lt;code&gt;deb&lt;/code&gt;만 활성화되어 있는데, &lt;code&gt;deb-src&lt;/code&gt; 라인의 주석을 풀고 &lt;code&gt;build-dep&lt;/code&gt;을 하면 해결됩니다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://sangwook.github.io/images/2016/161011-ubuntu16-vim-version.jpg&#34;&gt;&lt;img src=&#34;http://sangwook.github.io/images/2016/161011-ubuntu16-vim-version.jpg&#34; alt=&#34;vim8&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;마지막으로, headphone으로 음악을 듣다가 headphone을 뽑으면 speaker는 자동으로 음소거되게 하고 싶었습니다. Ubuntu14 Unity에서는 headphone과 speaker 각각에 대해 제가 조정한 소리 크기를 자동으로 기억해 주었기 때문에 알아서 잘 동작했습니다. KDE는 제 선택을 기억하지 않습니다. 해결책은 시간 있을 때 다시 찾아봐야겠습니다.&lt;/p&gt;
</content>
<author><name></name></author>
<summary type="html">
오랫동안 Ubuntu 14.04 LTS를 써 왔습니다. Unity는 불편했지만 그럭저럭 적응하며 익숙해졌습니다. 그래도 다음 OS에서는 Unity를 쓰지 말자고 다짐했습니다. 왜냐고 물으면 명확하게 답을 못 하겠습니다. 살짝 느린 느낌이 든다는, 제가 싫어하는 비과학적인 답을 해야 합니다. 아무튼 다음에는 archlinux나 debian처럼 rolling …</summary>
</entry>
<entry>
<title type="html">Uber가 PostgreSQL을 MySQL로 바꾼 이유</title>
<link href="https://sangwook.github.io/2016/09/13/uber-mysql-postgresql.html" rel="alternate" type="text/html" title="Uber가 PostgreSQL을 MySQL로 바꾼 이유" />
<published>2016-09-13T19:05:00+09:00</published>
<updated>2016-09-13T19:05:00+09:00</updated>
<id>https://sangwook.github.io/2016/09/13/uber-mysql-postgresql</id>
<content type="html" xml:base="https://sangwook.github.io/2016/09/13/uber-mysql-postgresql.html">&lt;p&gt;&lt;a href=&#34;https://eng.uber.com/mysql-migration/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://eng.uber.com/mysql-migration/&lt;/a&gt; 글을 읽었습니다. Postgres의 단점을 매우 잘 정리한 글입니다. 사실 이 글은 아래 그림 한 장으로 요약할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/assets/2016/160913-14-48-36-bd8179f631639ed57e34af915ad9219c72394594d204fee87db0c4c17479fedd.jpg&#34; alt=&#34;이미지&#34;&gt;&lt;/p&gt;
&lt;p&gt;읽고 난 뒤 정리한 메모를 최대한 짧게 줄이면 다음과 같습니다.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;항목&lt;/th&gt;
					&lt;th&gt;PostgreSQL&lt;/th&gt;
					&lt;th&gt;MySQL (InnoDB)&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;secondary index&lt;/td&gt;
					&lt;td&gt;directly&lt;/td&gt;
					&lt;td&gt;indirectly&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;secondary key lookup&lt;/td&gt;
					&lt;td&gt;유리&lt;/td&gt;
					&lt;td&gt;불리 (index 2개를 찾아야 하니)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;row update 시&lt;/td&gt;
					&lt;td&gt;모든 index 업데이트&lt;/td&gt;
					&lt;td&gt;해당 row의 index만 업데이트&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;replication&lt;/td&gt;
					&lt;td&gt;WAL을 보냄&lt;/td&gt;
					&lt;td&gt;commands를 보냄&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;MVCC&lt;/td&gt;
					&lt;td&gt;row를 항상 씀&lt;/td&gt;
					&lt;td&gt;변경전 row를 rollback segment에 복사.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;cache&lt;/td&gt;
					&lt;td&gt;OS의 page cache&lt;/td&gt;
					&lt;td&gt;buffer pool&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;connection&lt;/td&gt;
					&lt;td&gt;conn 당 process 생성&lt;/td&gt;
					&lt;td&gt;conn 당 thread 생성&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;upgrade&lt;/td&gt;
					&lt;td&gt;downtime 필요.&lt;/td&gt;
					&lt;td&gt;downtime 없이 가능.&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;덧붙이는 말입니다.&lt;/p&gt;
&lt;p&gt;이 글에는 Postgres의 단점만 적혀 있습니다. 그러나 Postgres가 tuple 방식의 디자인을 선택한 것은 일종의 tradeoff이고, 장점도 많습니다. 다만 커넥션마다 프로세스를 새로 만드는 방식이 어떤 장점이 있는지는 아직 잘 모르겠습니다. 제가 모르는 이유가 있을 텐데, 어떤 기술을 비판하는 일은 결국 무지에서 비롯되는 경우가 많아 조심하려고 합니다.&lt;/p&gt;
</content>
<author><name></name></author>
<summary type="html">https://eng.uber.com/mysql-migration/ 글을 읽었습니다. Postgres의 단점을 매우 잘 정리한 글입니다. 사실 이 글은 아래 그림 한 장으로 요약할 수 있습니다.
읽고 난 뒤 정리한 메모를 최대한 짧게 줄이면 다음과 같습니다.
항목 PostgreSQL MySQL (InnoDB) secondary index directly …</summary>
</entry>
</feed>
