데이터 기법은 문제를 제거하는 기술이 아니라, 문제를 다른 형태의 비용으로 바꾸는 기술이다
컴퓨터 공학에 데이터 기법들은 어떤 것들이 있을까?
- 인덱스, 캐싱, 샤딩, 파티셔닝, 압축, 동기화, 동시성, 실시간성, 최종 일관성,
- 여기에 분산에서의 데이터 처리
- 그외 등등..
아 피곤하다. 데이터란 놈은 왜 이렇게 뭐가 많을까.
그래서 오늘은 각각이 뭔지는 잠깐 접어두고, 왜 이따위 짓을 해야 하는지부터 이야기해보고 싶다.
그러면 궁금한 게 하나 있다. 데이터란, 대체 뭘까?
데이터란 무엇인가
막상 물으니 "값?" 정도만 떠오르긴 한다.. 조금 두루뭉실하죠 다들?
조금 철학적으로 들어가면, 데이터는 이 세상을 구별하는 매개체다.
데이터를 지운다는 게 뭘까? 흔히는 무언가를 없앤다고 생각한다. 하지만 더 정확히 말하면, 구별을 없애는 일이다.
새하얀 종이를 떠올려 보자. 어디를 봐도 똑같다면 거기엔 구별이 없다. 그런데 점 하나를 찍는 순간 점 있는 곳과 없는 곳이 갈라진다. 우리는 그 차이를 보고 정보를 읽는다.
그래서 정보는 점 자체에도, 여백 자체에도 있지 않다. 둘이 서로 다르다는 사실에 있다.
컴퓨터도 마찬가지다. 컴퓨터는 세상을 0과 1로 구별한다. 0이 '없음'이고 1이 '있음'이라서가 아니다. 둘이 서로 구별되기 때문이다. 결국 데이터란 무엇이 있는가의 문제가 아니라, 무엇과 무엇이 다른가의 문제다. (중요한 이야기는 아닌데,, 그냥 쓰고 싶어서 작성했다.. 교양차 읽어보면 좋을듯?)
읽기와 쓰기에 대해
근데 이러한 데이터를 다룰 때 골치가 하나 생기는데, 바로 읽기와 쓰기다.
데이터를 읽고 쓰는 게 왜 문제일까?
만약 저장소와 연산 장치가 완전히 같은 하나라고 가정해보자.
그러면 읽기와 쓰기라는 개념 자체가 희미해진다.
데이터를 옮길 필요 없이 상태만 바뀌면 되기 때문이다.
하지만 현실의 컴퓨터는 저장하는 곳과 사용하는 곳이 항상 분리되어 있고, 그래서 읽기와 쓰기를 피할 수 없다.
읽기가 뭔지부터 다시 보자. 읽기가 성립하려면 숨은 전제가 하나 깔려 있다.
데이터가 머무는 자리와 데이터를 사용하는 자리가 서로 달라야 한다.
만약 둘이 완전히 같은 곳이라면 가져올 것도, 써넣을 것도 없다. 하지만 현실에서는 데이터는 여기 있고, 그 데이터를 써야 하는 곳은 저기 있다. 그래서 우리는 데이터를 옮겨야 한다.
결국 읽기와 쓰기의 본질은 데이터를 이동시키는 일이다.
문제는 데이터를 옮기는 순간 생긴다. 내가 어떤 자리를 읽었다고 해보자. 그런데 그 사이 누군가 그 자리에 새로운 값을 써버렸다.
내 손에 들고 있는 건 방금 전의 데이터고, 원본은 이미 달라졌다. 분명 같은 데이터를 읽었다고 생각했는데 지금의 진실과는 어긋난다.
컴퓨터공학의 수많은 데이터 기법은 대부분 여기서 출발한다. 데이터를 어디에 둘 것인가, 얼마나 빨리 가져올 것인가, 읽어 온 데이터가 아직도 최신인지 어떻게 보장할 것인가.
결국 데이터 기법이란, 서로 다른 자리 사이에서 데이터를 읽고 쓰는 과정에서 생기는 문제를 푸는 방법이다.
거리와 시간
데이터를 읽고 쓴다는 이야기를 조금 더 들여다보면, 결국 문제는 두 가지이다. ---> 거리와 시간
거리의 문제
데이터는 점점 더 멀리 있다.
CPU는 캐시를 보고, 캐시는 메모리를 보고, 메모리는 SSD를 보고, SSD는 다른 서버를 보고, 서버는 또 다른 데이터센터를 본다.
시스템 규모가 커질수록 데이터는 멀어지고, 멀어진 데이터는 더 오래된 데이터가 된다.
거리가 멀면 멀수록 가져오는 데 오래 걸린다.
우리가 성능 문제라고 부르는 것들의 상당수는 결국 이 거리에서 나온다.
하지만 데이터를 가져오는 순간 또 다른 문제가 생긴다.
시간의 문제
내가 데이터를 읽은 순간과 그 데이터를 사용하는 순간은 완전히 같을 수 없다.
읽어 오는 동안 누군가 새로운 값을 쓸 수도 있고, 여러 곳에 복사된 데이터들이 서로 다른 상태를 가질 수도 있다.
내가 보고 있는 값이 지금도 최신인지, 아니면 이미 과거가 되어버렸는지는 언제나 의심할 수밖에 없다.
물론 실제 시스템에는 저장 공간, 계산 비용, 데이터 규모 같은 다른 문제들도 존재한다.
하지만 규모가 커질수록 데이터는 더 멀어지고, 멀어진 데이터는 더 큰 시간 차이를 만든다.
그래서 많은 데이터 기법들은 결국 거리와 시간의 문제로 다시 모인다.
데이터가 너무 멀리있다.. 이걸 어껍게 가깝게 할까?
그리고 데이터를 읽는 동안.. 세상이 바뀌고 있다..
그래서 데이터 기법은 결국 무엇을 희생하는가
재밌는 건 대부분의 데이터 기법이 새로운 문제를 푸는 게 아니라, 위에서 말한 시간과 공간 중 하나를 메우기 위해 다른 것을 희생하는 선택이라는 점이다.
예를 들어 캐시는 거리의 틈을 줄이는 방법이다.
멀리 있는 데이터를 매번 읽지 말고 가까운 곳에 복사해 둔다.
그대신 원본은 이미 바뀌었는데 캐시에 남은 데이터는 예전 값일 수 있다.
즉 캐시는 거리 문제를 해결하는 대신 시간 문제를 떠안는다.
실시간성을 조금 포기해서 속도를 얻는 셈이다.
정규화와 비정규화도 비슷하다.
정규화는 데이터를 한 곳에만 둔다.
그렇게 하면 쓰기에는 유리하다. 수정할 곳이 하나뿐이니까,,
하지만 읽을 때는 여기저기를 찾아다녀야 한다.
반대로 비정규화는 데이터를 여러 곳에 복사한다.
여려 곳에 저장하니 읽을 때마다 다른 테이블을 볼 필요가 없으니, 읽기는 빨라진다.
하지만 수정할 때는 복사된 모든 곳을 고쳐야 한다,,
즉, 정규화는 읽기를 희생해서 쓰기 성능을 올린 것이고, 비정규화는 쓰기를 희생해서 읽기 성능을 올린 트레이드오프이다.
인덱스도 마찬가지다.
원하는 데이터를 빨리 찾기 위해 별도의 데이터를 따로 유지한다.
그래서 원하는 것만 읽어서, 읽기는 빨라진다.
하지만 데이터를 추가하거나 수정할 때마다 인덱스도 함께 갱신해야 한다.
결국 쓰기가 더 비싸진다.
결국 본질은 단 하나,,
캐시도, 정규화도, 비정규화도, 인덱스도 전부 중요한 기술처럼 보이지만 사실 새로운 능력을 만들어내지는 못한다.
캐시가 있다고 해서 원래 읽을 수 없던 데이터를 읽게 되는 것은 아니다.
인덱스가 있다고 해서 없던 데이터가 생기는 것도 아니다.
정규화와 비정규화 역시 데이터 자체를 바꾸지는 않는다.
이 기술들은 문제를 없애기보다 문제의 위치를 바꾼다.
거리를 줄이면 최신성을 관리해야 하고,
읽기를 빠르게 만들면 쓰기가 비싸지고,
중복을 줄이면 조회가 복잡해지고,
조회가 쉬워지면 수정이 어려워진다.
무언가를 얻는 순간 다른 곳에서 비용을 지불하게 된다.
그래서 데이터 시스템 설계는 마법 같은 최적화를 찾는 일이 아니다.
어떤 문제를 해결할 것인가보다, 어떤 문제를 받아들일 것인가를 결정하는 일에 가깝다.
결국 데이터 기술은 늘 같은 두 질문으로 돌아온다.
데이터는 항상 내가 있는 곳이 아닌 다른 곳에 있다. 그리고 그 데이터를 가져오는 동안 원본은 계속 변한다.
우리는 항상 기억하자.
데이터 기법은 문제를 제거하는 기술이 아니라, 문제를 다른 형태의 비용으로 바꾸는 기술이다
우리는 어떻게 수많은 데이터 기법들은 활용해 우리의 서비스를 잘 해결해 나가야 할까?