-
데이터베이스 기술은 '있으면 좋은' 것이 아닙니다.칼럼 2023. 11. 14. 22:07
원문 : 데이터베이스 기술은 '있으면 좋은' 것이 아닙니다. (renegadeotter.com)
Your database skills are not 'good to have'
And a hateful ode to Object-Relational Mappers
renegadeotter.com
Database 전문가는 ORM을 싫어합니다. TDD 개발자는 ORM을 좋아합니다. 누군가는 그 둘을 모두 싫어합니다.
사라져가는 SQL의 기술
지난 몇 년 동안 나는 소프트웨어 엔지니어들이 이국적인 "행성 규모"를 사용하기를 열망하는 불안한 추세를 알아 차렸다 매우 초보적인 문제에 대한 데이터베이스이지만 동시에 매우 강력한 문제를 잘 파악하지 못합니다. 관계형 데이터베이스 엔진은 기술의 고급 및 유용한 기능을 이해하는 것은 고사하고 이미 사용하고 있을 가능성이 높습니다. SQL 계층은 라이브러리 아래 깊숙이 묻혀 있고 절반의 ORM에 의해 너무 영리하여 모든 것이 높은 수준이됩니다 코드.
최신 하드웨어는 확실히 CPU에서 더 높은 추상화 계층으로 올라갈 수 있게 해주지만 그렇지 않았습니다 과거에는 성능의 모든 비트를 짜내기 위해 특정 함수를 어셈블리 코드로 변환하는 것이 드문 경우였습니다. 프로세서. 이제 컴퓨팅과 스토리지가 더 저렴해졌지만(사실이지만) 이 풍요로움을 남용하는 것은 우리를 훈련시켰습니다 게으름과 안일함. 갑자기, 그 구름 청구서가 너무 높아졌고, 하늘은 그 방법을 알고 있습니다 매머드에 대해 매초 수십억 개의 비효율적인 ORM 쿼리를 실행하여 전 세계가 많은 에너지를 태우고 있습니다 데이터베이스 인스턴스.
2004년 첫 면접을 보던 날 아침, 나는 지하철 안에서 외우고 있었다 데이터베이스 정규화의 9개 수준입니다. 아니면 5단계인가요? 나는 기억하지 못하고, 그것은 중요하지 않습니다 - 아무도 없을 것입니다 지금 소프트웨어 엔지니어 인터뷰에서 이 질문을 던져보세요.
선택한 데이터베이스의 목차를 훑어보기만 하면 지금 갓 유행하는 Postgres가 있습니다. 가장 섬뜩한 것을 제외한 모든 것을 처리할 수 있는 기능의 절대적인 보물창고를 찾을 수 있습니다 전 세계적인 규모의 컴퓨터 과학 문제. 복제된 페타바이트 크기의 Postgres 상자는 이제 다음과 같이 쉽게 실행됩니다. 이 글을 읽고 있습니다.
비결은 데이터베이스나 ORM이 당신의 마음을 읽을 것이라고 기대하지 않는 것입니다. 말이 나왔으니 말인데...
ORM은 친구이자 적입니다
저는 한때 전자 상거래 업체의 신입 사원이었고 즉시 심각한 성능 문제를 해결하는 데 투입되었습니다. 회사의 제품 카탈로그 페이지. 제품 이미지의 간단하고 페이지가 매겨진 그리드입니다. 얼마나 어려울까요? 믿거나 말거나, 그렇지 않습니다. 페이지를 로드하는 데 10초 이상이 걸렸고, 때로는 더 오래 걸렸으며, 데이터베이스가 어려움을 겪었고, 해결책은 "그냥 캐시". 마지막 데이터 포인트 - 트래픽이 많은 사이트가 아니 었습니다. 트래픽이 전혀 없더라도 페이지가 매우 느렸습니다. 그것은 뭔가 심각하게 잘못되었다는 썩은 신호.
조금 더 자세히 살펴본 후, 나는 상위 3 대 주요 데이터베이스와 코딩 실수를 모두 하나로 묶었다는 것을 깨달았습니다.
❌ 실수 #1: 인덱스가 없다
모든 단일 미션 크리티컬 쿼리에서 적중된 열에는 인덱스가 없었습니다. 없음. 에 절실히 필요한 색인을 추가 한 후 프로덕션에서는 MySQL이 안도의 숨을 내쉬는 소리를들을 수 있습니다. 그래도 아직 성능이 좋지 않았기 때문에 이제 코드에서 더 깊이 파고들어야했습니다.
❌ 실수 # 2 : 각 ORM 호출이 무료라고 가정합니다.
쿼리 로그를 로컬로 활성화하고 제품 목록 페이지를 다시로드하면 ... 200개, 300개, 500개의 쿼리가 하나의 쿼리를 로드하는 데만 실행되었습니다. 단일 페이지. 뭐야 젠장? 밝혀진 바에 따르면, 이것은 루프의 모든 레코드를 통과하는 고전적인 ORM 남용의 결과였습니다. 효과:
for product_id in product_ids: product = amazing_orm.products.get(id=product_id) products.append(product)
쿼리 수가 많은 이유는 이 논리 중 일부가 중첩되었기 때문이기도 합니다. 명백한 해결책은 각 요청의 쿼리 수를 최소한으로 줄이고, SQL을 활용하여 데이터를 하나의 단일 Blob으로 조인하고 결합합니다. 이것이 바로 관계형 데이터베이스는 이름에 있습니다.
각 개별 쿼리는 데이터베이스로 이동하고, 구문 분석, 변환, 분석, 계획, 실행, 그런 다음 발신자에게 다시 이동합니다. 그것은 중 하나입니다 당신이 할 수있는 가장 비싼 작업, 그리고 ORM은 행복하게 당신을 위해 최악의 일을 할 것입니다. 공연. ORM 호출은 어떻게 SQL로 변환됩니까? 그것이 당신이 생각해야 할 것이 아니라면, 그것은 ORM 제한입니까, 아니면 당신입니까? 그냥 사용하지 않습니다 올바른 도서관 호출? ANSI가 아닌 SQL의 특정 버전을 사용하고 있으며 특정 ORM이이를 잘 지원하지 않습니까? 네가 이 호출에 대해 원시 SQL로 드롭해야하지만 다른 호출은 필요하지 않습니까? 등등.
❌ 실수 #3: 세상 속으로 끌어들이기
설상가상으로 데이터의 양은 비교적 적었지만 열은 수십 개에 달했습니다. ORM은 무엇을합니까? 일반적으로 당신의 삶을 "더 쉽게"만들기 위해 기본적으로합니까? 그들은 모든 것, 모든 열을 전송하여 네트워크를 막습니다 필요하지도 않은 데이터로 파이프합니다. 그것은 유독한 기술 부채의 한 형태이며, 개발 속도는 결국 성능을 갉아먹기 시작합니다.
나는 같은 프로젝트 내에서 Dango 관리자의 어두운 구석을 해킹하는 데 몇 시간을 보냈고 기본 ORM 쿼리를 덜 무시했습니다 "열심히". 이것은 이끌었다 훨씬 더 나은 사무실 대면 경험.
성능은 기능입니다.
진지하고 미션 크리티컬한 시스템은 수십 년 동안 고전적이고 지루한 관계형 데이터베이스에서 실행되어 수천 개의 초당 요청 수. 이러한 시스템은 더욱 발전하고, 더 많은 기능을 갖추고, 더 관련성이 높아졌습니다. 그들은 컴퓨터의 경이로움입니다 과학이라고 주장할 수 있습니다. Postgres (1982 년 이후 개발 중)와 같은 고대 데이터베이스가 일종의 이 시점에서 레거시 유지 관리 모드이지만 그 반대입니다. 사실, 이 작업은 규모와 함께 가속화되고 있습니다 그리고 기능이 꽤 인상적이됩니다. 불과 몇 년 전만 해도 여러 개의 쿼리를 받았지만 이제는 하나의 쿼리로 처리합니다.
이것이 중요한 이유는 무엇입니까? 아마존에서 발견 한 것처럼 오랫동안 알려져 왔지만, 페이지가 로드되기를 기다리는 사용자가 100ms를 추가할 때마다 비즈니스 비용을 잃게 됩니다. 우리는 또한 이제 사용자의 웹 페이지의 최대 목표 응답 시간은 약 100밀리초입니다.
100밀리초 미만의 지연은 사용자에게 즉각적으로 느껴지지만 100밀리초에서 300밀리초 사이의 지연은 인식할 수 있습니다. 300밀리초에서 1,000밀리초 사이의 지연은 사용자가 기계가 작동하는 것처럼 느끼게 하지만 지연이 1,000밀리초를 초과하면 사용자가 정신적으로 컨텍스트 전환을 시작할 수 있습니다.
"속도가 느리면 CPU와 RAM을 더 추가하자"는 접근 방식이 한동안 효과가 있었을지 모르지만 많은 사람들은 비용이 중요한 검소한 비즈니스 환경에서 이러한 종류의 게으름이 지속 가능하지 않다는 것을 어렵게 깨닫고 있습니다.
데이터베이스 안티패턴
하지 말아야 할 것을 아는 것은 무엇을 해야 하는지 아는 것만큼 중요합니다. 아래 실수 중 일부는 너무 일반적입니다.
❌ 안티 패턴 #1. 잘못된 이유로 이국적인 데이터베이스 사용
DynamoDB와 같은 기술은 Postgres 및 MySQL에 장애가 발생하기 시작하는 규모를 처리하도록 설계되었습니다. 이것은 다음과 같이 달성됩니다. 비정규화, 데이터 복제, 데이터베이스가 실시간 데이터 조작 또는 조인을 많이 수행하지 않는 경우. 이제 데이터는 데이터가 관련되는 방식이 아니라 쿼리되는 방식에 따라 모델링됩니다. 규칙적인 관계 개념은 이때 붕괴된다 미친 수준의 규모. 말할 필요도 없이, "일반적인 규모" 문제를 해결하기 위해 이러한 종류의 스토리지에 의존하고 있다면 이미 가지고 있지 않은 문제를 해결하고 있는 것입니다.
❌ 안티 패턴 #2. 불필요하게 캐싱
캐싱은 필요악이지만 항상 필요한 것은 아닙니다. 다음과 같은 전체 종류의 버그와 당직 문제가 있습니다. 오래된 캐시된 데이터에서 비롯됩니다. 읽기 전용 데이터베이스 복제본은 다음과 같은 고전적인 아키텍처 패턴입니다. 여전히 구식이 아니며 걱정할 필요가 없기 전에 미친 수준의 성능을 구입할 것입니다. 술래 해야 한다 아니 성숙한 관계형 데이터베이스에는 이미 쿼리 캐싱이 있다는 사실에 놀랐습니다 - 특정 요구 사항에 맞게 조정하기만 하면 됩니다.
캐시 무효화는 어렵습니다. 그것은 더 많은 복잡성과 상태를 추가합니다. 시스템에 대한 불확실성. 디버깅이 더 어려워집니다. 콘텐츠 팀으로부터 내가 신경 쓰는 것보다 더 많은 이메일을 받았습니다. 내 경력 내내 "왜 데이터가 거기에 없지, 30 분 전에 업데이트했습니까?!"
캐싱은 잘못된 아키텍처와 성능이 좋지 않은 코드에 대한 임시방편으로 작용해서는 안 됩니다.
❌ 안티 패턴 #3. 모든 것과 부엌 싱크대 보관
업계 표준 데이터베이스가 감당할 수 있는 만큼의 처벌을 감수할 수 있지만, 무슨 일이 일어나고 있는지 전혀 신경 쓰지 않는 것은 좋은 생각이 아닐 수 있습니다 에 일종의 데이터 매립지처럼 취급합니다. 관리, 쿼리, 백업, 마이그레이션 - DB가 커지면 모두 고통스러워집니다. 실질적 으로. 그것이 당신이 사용하고 있기 때문에 그것이 중요하지 않더라도 관리형 클라우드 DB - 비용이 있어야 합니다. RDBMS는 정교한 기술이며 데이터를 저장하는 데 비용이 많이 듭니다.
먼저 공통 규모를 파악하십시오.
추가 기능없이 마법을 부릴 것으로 기대한다면 두툼한 Postgres 또는 MySQL 데이터베이스를 중단시키는 것은 매우 쉽습니다 일하다. "그건, 웹 스케일이 아닙니다, 보스. 200만 돌파 기록은 너무 큰 성과인 것 같습니다. DynamoDB, Kafka 및 이벤트가 필요합니다. 소싱!"
관계형 데이터베이스는 우리 기술 화석들만이 전문가가 되기로 선택한 구식 기술이 아닙니다 성가신 곤충처럼 손을 흔들었다. "여기서 우리는 모든 것을 반응하고 GraphQL합니다, 늙은이". 법적으로 말하자면, 현대의 RDBMS는 다음과 같습니다 유죄가 입증되기 전까지는 무죄이며, 입증 책임은 매우 커야 합니다 높고 거의 전적으로 당신에게 달려 있습니다.
마지막으로, "왜 느린지"를 알아 내야한다면 대략적인 Runbook은 다음과 같습니다.
- 로깅, 느린 쿼리 로그 등에서 고유한 쿼리 목록을 컴파일합니다.
- 가장 빈번한 쿼리를 먼저 살펴봅니다
- 인덱스 사용량에 대한 느린 쿼리 계획을 확인하는 데 사용합니다.EXPLAIN
- 유선을 통해 이동해야 하는 데이터만 선택
- ORM이 해결 방법없이 어리석은 일을하고 있다면 후드를 열고 원시 SQL 배관으로 더러워집니다
가장 중요한 것은 데이터베이스(및 SQL)를 연구하는 것입니다. 배우고, 사랑하고, 사용하고, 남용하십시오. 잎사귀를 날리는 데 며칠을 보냅니다. Postgres 매뉴얼을 통해 무엇을 할 수 있는지 확인하면 다음 작업에 더 많은 시간을 할애하는 것보다 더 나은 엔지니어가 될 수 있습니다 이달의 맛 JavaScript 프레임워크의 뜨거움. 다시.
'칼럼' 카테고리의 다른 글
GM-NAA I/O 및 SHARE의 역사 (0) 2023.12.03 모든 소프트웨어는 지저분하고 뼈대가 있습니다 (1) 2023.11.21 개발에 관하여 하고 싶은 이야기 : 파트 2 - 데이터베이스 다중화 (1) 2023.11.14 개발에 관한 하고 싶은 이야기 : 파트1 - 웹 개발과 분산 (1) 2023.11.14 웹 개발자가 되기 전에 반드시 알아야 하는 내용 (0) 2023.11.12