도커(Docker)와의 조우, 그리고 mySQL
VS Code 익스텐션으로 처음만난 친구다. 이름도 외모도 귀엽게 생겨서 설치는 했는데 어떻게 쓰는줄을 몰라서 무용지물이었다.
위에 글은 링크에 링크가 있고, 아래 유튭 영상이 개념상 이해할만 했다. 그러니까 이해한대로 요약해보자면 도커란 녀석은 로고 그대로 엄청난 컨테이너를 적재하고 항구에 달려와서 port
열어 외치고, 컨테이너를 질서있게 적재하는 인천항의 모습을 담고있는 그런 녀석인 것 같다. 영상 설명을 빌리자면 컨테이너에 달린 창문으로 통신 같은걸 할 수도 있다.
그리고 도커 안에 mySQL 을 설치해 볼 계획이다. 지금까지 나는 막연하게도 mySQL 이라는건 서버(?) 같은건 줄 알았고, (사실 서버가 뭔지도 모른다.) 예전부터 사용되던 거라 요즘엔 안쓰는건줄 알았다. (무식은 이렇게 용감하다.) 오라클, SQL 이런 녀석들이 한통속이었고, 아직도 엄청 잘나가는 존재들이라니… 오늘 DB라는 걸 만들어보면서 정말 새롭게 알게 된 것들이 많다.
세상이 부쩍 넓어보인다.
1. Docker 를 설치해보자.
도커를 설치하는 이유는 사실 뒤늦게 깨달은 docker
의 엄청난 역할과는 상관없이 mySQL
을 설치하고, DB
를 살짝 구축하는 연습을 하기 위해서였다. 그래서 시작과 동시에 나에게는 몇가지 선택지가 주어졌다.
1
2
3
4
5
1. Windows 에 mySQL 을 설치한다. (도커 무의미)
2. WSL 에 docker 를 설치한 후 mySQL을 설치한다. (GUI도 없을 것 같은데 미지의 세계를 CLI와 함께 떠나기는 싫다.)
3. VMware 에 설치된 Ubuntu 에 docker 를 설치하고, 거기에 mySQL을 설치한다. (꼭 그래야되나)
4. VMware 에 설치된 Ubuntu 에 mySQL 을 설치한다. (도커 무의미)
5. Windows 에 Docker 를 설치하고, mySQL 을 설치한다. (돌이켜보니 선택의 여지가 없었던 것 같다.)
- 도커를 설치해보는 연습을 하고, 경험해보기 위해
- vmware 보다 docker 가 자원을 덜 소모한다고 해서 (OS가 두개 돌아간다고 한다. 집 안에 집을 짓는거라고..)
- 이런 이유로 5번을 선택했다. 설치는 기도메타… 제발 한방에 가자…
음.. 색감이 밝고 좋다. 마음에 든다.
- Download for Windows
- 여기까진 좋다.
- 잠시 반응이 없어서 멈췄나 싶었지만
- 다행히 성공했고, 바로 재부팅
- 재부팅하자마자
WSL 2 intallation is incomplete
오류가 떴고, 링크에 접속해 봤다. - 사실 얼마전 bash shell 을 만지면서 WSL2 를 설치해야 할 이유가 생겼는데 Windows OS build 버젼이 낮은 이유로 포기했었다.
- CS 를 조금 공부하고 난 이후로 ‘커널(kernel)’ 이라는 말이 별로 반갑지가 않다.
- 업데이트 패키지가 있어서 일단 업데이트를 해봤고,
- 다행히 성공적으로 업데이트가 됐다.
- 그리고 WSL 2를 기본 버전으로 설정하는데, 저번에도 했었던 작업같다.
- 그 때도 뭔가 찝찝했는데 제대로 한거라면 왜 또 업데이트를 하라는 메세지가 나왔을까. 조금 불안하다.
- 그래도 한 번 해봤는데, 별다른 메세지가 없어서 넘어갔다.
- 그리고 이미 실행되고 있는 도커를 봤더니 에러를 내고 있었다.
- 그치만 다행히 큰 일은 아니었던 것 같다. 리셋시켰다.
- 처음 만나는 도커! 심지어
a few easy steps
를 제공한다. - 하지만 이 상태로 두고, 가이드를 따라 CLI 로 설치를 진행했다.
- 도커에 대한 개념같은거 아예 없는 상태였던 것 같다.
- 나중에 보니
a few easy steps
를 CLI 에서 진행했던 것 같다.- Git 을 처음 만났을 때, git init 을 하고, 글로벌 유져를 설정하고, 원격지에 remote 했던 것처럼 GUI 에서도 할 수 있는 작업을 CLI로 먼저 해보게 된 것 같다.
- Git 도 CLI 에서 사용할 줄 아는게 좋다고 했으니, 이번에도 마찬가지라고 생각해야겠다.
- 어서 CLI 에 익숙해지자. 열라 무서운데 지지 말아야지….
2. Docker 에 mySQL 설치하기
버전 확인
- 나는 mysql 이미지 중에 별이 가장 많은걸 받았다.
1
$ docker pull mysql
- 도커는 환경을 이미지처럼 기억해놓는데, 그 모양을 다양하게 따로따로 다 담아낼 수 있다고한다.
- 설치 후 알았는데 docker hub 에 가니까 눈으로 보면서 찾을 수 있었다.
1
$ docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password --name mysql_test mysql
docker 안에 컨테이너를 만들었다.
그런데 컨테이너는 백그라운드에서
-d
데몬으로 돌아가고 있게하고, (그렇지 않으면 터미널 하나를 점유한다.)root password 는
password
이고… (엔터치고 나면 설정하라고 나올줄 알았다…)컨테이너 이름은 역시나
mysql_test
이다.
1
docker ps -a
- 컨테이너 동작 확인
1
docker exec -i -t mysql_test bash
- mysql bash 접속
일단 여기까지 성공하고 나서 잠시 잊고있던 데스크탑 Docker를 구경하기로 했다.
아이콘이 하나 생겼는데 귀엽다.
- 오호라 그러니까
docker
를 시작할 때, 필요한 단계는clone
,build
,run
정도인 것 같다. - shell 도 있고 좋아보인다. 하지만 나는 CLI 로 해볼거다.
- 신기하게도 내가 만든 이미지가 GUI 에도 생겼다.
- 확실히 vm 보다는 가볍게 돌아가고 있다.
3. mySQL 접속해보기
1
$ mysql -u root -p
-u
는 유저이름-p
는 패스워드- 바로 패스워드를 입력해도 되지만 히스토리에 남는다.
- 뭔가 다른 세상에 온 것 같은데
SSL
같은 것도 있고, 제대로 설치가 된 것 같긴하다. characterset
이latin1
인걸utf8
로 세팅을 해줘야 한글이 제대로 인코딩이 된다고 한다.- 숫자, 영어, 특수문자 = 1byte, 한글 = 2byte, 이모지 = 4byte 라서 이모지 설정을 위해서는 따로 설정이 더 필요했다.
- 하지만 이모지를 넣어볼 시간이 없다.
- sql 내부에 설정 파일이 여러개 있었고, 로딩하면 안내메세지로 커스터마이징 할 때 사용할 파일을 알려주는 것 같다.
처음으로 만나보는 데이터베이스!
sql 문법은
;
이 꼭 필요한 것 같다. 깜빡하고 엔터를 치면>
이상태가 되는데 여기에서 세미콜론을 입력해도 명령어는 실행된다.
대소문자를 구분하지 않는것 같고, 인덴트도 필요 없는 것 같다.
characterset
을 하면서 엄청난 삽질을 했다.mysql 문법인지 linux 명령어인지도 헷갈리고, 내가 어디있는지도 헷갈렸고, 심지어 가이드에 나온 파일 경로가 내가 설치한 것과 조금 달랐다.
shell 명령어에
cat << 'EOL' > /etc/bin/conf.d/utf8.cnf
이런 내용이 있으면 겁이 났는데 오늘 공부가 좀 됐다.- 제대로 이해한건지 모르겠지만
<<
연산자는standard input
을 이야기하는 것 같고, 저렇게 하면 막 입력이 된다.- ‘EOL’ 은 ‘end of line’ 이라는 뜻의 약속어로 쟤가 있는 곳까지 읽어 내려간다.
cat
은 없는 폴더까지 만들어주진 않고, 존재하는 경로의 폴더까지 찾아가면 파일은 만들어준다.
그리고 내 경우에는 해당하지 않아서 쉽게 지나간듯 엄청 시간을 끌었던 부분이 있었는데, 바로
127.0.0.1
의bind
를 주석처리하는 일이었다.어떤 이유인지 mysql을 온통 돌아다녀도
grep -r 'bind'
로 잡히는게 없었다. 그런데 왜 그걸 주석처리 해야하는지 몰랐으므로HeidiSQL
로db
에 접속해놓고도 그것땜에 한참을 헤맸다.그 와중에 컨테이너 bash쉘이 불편하다고
curl
도 설치하고,zsh
도 설치했으나 별 효과가 없었다.이미지 히스토리가 있는걸 발견하고, 읽어보기까지 하게 됐다.
뭐 재미는 있었다. 뭔가 bash 최소 설치버젼을 깔아놓은것 같다. 깡통이다 깡통. sudo도 없다.
- 이 또한 깃에서
fork
나source tree
와 같이 GUI 프로그램인 것 같다. - 처음만난 녀석치곤 친절하게 접속을 허가해줬고, 내가 모르는 엄청 다양한 기능을 가지고 있는 프로그램 같다.
윈도우에서 사용할 수 있는 프로그램 선택지로는
bench work
와heidi sql
이 있었는데, 그냥 이걸로 해봤다.먼저
database
의user database
를 만들어보았다.raccoonDB
가 생겼다. 여기서부터 흥분..
CREATE TABLE `user_log` (
`nickname` VARCHAR(64) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
`money` DECIMAL(10,2) NULL DEFAULT NULL,
`last_visit` DATETIME NULL DEFAULT NULL
)
COMMENT='nickname varchar(64),\r\nmoney dec(10, 2),\r\nlast_visit datetime'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
- 다음으로는
raccoonDB
에 위에 있는 것처럼 테이블을 생성했다. - 사실 저렇게 입력했을 때, 계속 실패를 했다.
- 오타도 났고, 결정적으로 마지막까지 실패한 이유는 내가 계속 인덴트를 했기 때문이었던 것 같다.
- GUI 에 오니 테이블도 만들고 열도 추가할 수 있어서 열을 추가하고, 데이터 유형도 살짝 공부해봤다.
- DB - 데이터 타입
- MySQL 데이터형 및 크기
mySQL 데뷔 첫 기념샷을 찍어봤다. 정말 데이터가 들어가는지 궁금해서 heidi sql로 입력하고, 다시
show tables
를 했더니 신기하게도 입력이 되어 있었다.그렇다면 세상에 돌아다니는 엄청난 정보들이 결국에는 이런식으로 저장되어 있단 말인가… 와….
라고 말한 후 넘나 정신없는 시간이 있었다. 바로 위에서 언급한 ‘bind’ 를 못찾은 이유때문이었다.
나는 mysql 에 root 권한으로 접속하고, db를 생성하면서
raccoon
이라는 유져가 하나 생성됐다.하지만 나는 계속 root 로 접속했고, gui 에서도 root로 접속했다. 그래서 자연스럽게 한 번에 외부접속에 성공을 해버렸다.
하지만 root 에게 외부접속 권한을 주는일은 사실 없어야 한다고 한다.
여기에서 유저를
drop
했다가select
로user
와host
를 뒤지기도 하면서 조금 이 환경에 아주 조~금 익숙해진것 같다.
4. npm mysql 로 mysql 과 통신하기
이제 이 테이블에 랜덤으로 생성한 데이터 100만개를 입력해야 한다. 직감했다. sql을 피하자. 최대한 피할 수 있는걸 궁리하다보니 npm
모듈이 다음 미션에 사용된다는게 보였다.
1
$ apt install mysql
- 바로 설치하려는데 경고가 뜨면서 잘 안됐다.
- 그래서 현제 사용하려는 폴더와 전역에 모두 여기저기 설치해봤다.
그리고 모듈이 잘 작동하는지 봤다.
그걸 확인하기 전에 해야할 일이 있다. 데이터를 생성할 수 있는 코드를 짜야한다.
- 요렇게!
- 어젯밤
DD
가 조언해준대로 클래스를 너져분하게 어질러놓지 않고, 파일을 나눠서 require 해봤다. - (ㅠㅠ
import
를 해보기엔 너무 바빴어요DD
)
- 그렇게 쿼리문 한줄로 mysql 서버와 통신하는데 성공했다.
5. 100만건을 어떻게 집어넣지?
다음 순서는 테이블에 백만건의 데이터를 입력하는 일이다. 여기까지 설치해오면서 어떻게 백만건을 처리할까의 고민을 하며 몇가지 대안을 생각해 봤다.
1
2
3
1. 타이핑한다. 엄청빨리! (그런데 랜덤값들이 있어서 한계가 있다. 복붙 불가능이다.)
2. 알고리즘 풀때 샘플데이터 넣어놓고 읽어오는 것처럼, 파일에서 읽어올까(사실 이게 제일 유효했고, 현재 도전해보고 있는 중이다. `DD` 는 이걸로 5초도 안걸려서 넣은 것 같다. 훌륭하다 역시... 난 한 30분 걸렸는데 이제 한 10분 걸린다 ㅎㅎ)
3. for 문으로 때려박아본다. (이번에도 용감했다.)
- 일단 한건, 10건씩, for문을 돌려봤다.
- 입력되는게 너무 신기할 뿐이다 ㅠㅠ 이정도면 노드몬 돌려놓고, 저장만 해도 되니까 한 반복회수 한 100에 맞춰놓고 10000번만 눌러주면 될것 같다. 응? 허…ㅎㅎ
- 1000건, 10000건 늘려가다가 이번엔 100000건 넣어볼까 하다가 0을 하나 더 넣어서 백만건을 돌리고 말았다.
- 그러자 타임에러가 났다.
- 반복문에
i
를 찍어보니 백만까지for
문이 돌기는 하는데 서버쪽에서 대기가 쌓여서 그런지 결국 한건도 안들어가고 오류를 냈다. - 현재 100000건 들어가는데 한 10분씩 걸리니까 나는 이거 10번만 하면된다. 1시간 40분?…
- 애초에 생각했었던
bulk insert
로 방향을 바꿔봤다. - 그러다가 대용량 INSERT 처리하기 글을 보게됐고, 얘네를 배열로 넣을 수도 있다는걸 알았다.
- 불현듯 스레드를 늘려볼까라는 생각을 하게됐고, 처음에는 반복횟수 1000000에 고정하고, 배열을 3개, 10개 이렇게 추가했는데, 한 20-30개 정도로 늘렸을 때 다시 먹통이 됐다.
- 그래서 반복횟수를 줄이면서 배열을 계속 늘려봤는데, 생각보다 속도도 조금씩 빨라지고, 쭉쭉 잘 들어가기 시작했다.
- 그래서 현재 백만건은 반복횟수 20000에 배열길이가 50이다 ㅎㅎㅎ
- 뭔가 데이터센터처럼 생겼다. 이건 코드다.
- 카운트를 찍으면서 데이터를 넣어봤는데, 미묘하지만
- 아래쪽이 좀 더 빠른 것 같기도 하고…
- 여차저차 해서 마지막에 50 * 20000으로 맞추니 10분 못걸려서 딱 백만건이 들어갔다.
6. 이렇게 된거 progress bar 에 도전해볼까… 물론 js로…
- 숫자가 올라가는 동안 카운트를 보다가 정적인 프로그레스 바를 한번 만들어봤다.
- 급조한것치고는 마음에 들어서 평소에 해보고 싶었던 거기도 하고해서 한번 해보기로 했다.
- 가장 큰 숙제는 문자열 출력이었는데 ㅎㅎ
console.log
로 찍다보니 줄바뀜 현상이 일어나고,sprocess.stdout.write
을 했더니 위와 같은 기괴한 현상이 일어났다…- 검색해보니
\r
캐리지리턴 식이 있어서 표준출력에 캐리지리턴을 더해주니 생각했던 프로그레스바가 완성 되었다.
- 오늘 안에 파일로 벌크 처리하는 방법까지 학습했으면 이 바가 조금 더 적극적으로 올라가는걸 볼 수 있었을텐데 지금은 굼벵이다.
참조
- 초보를 위한 도커 안내서 - 도커란 무엇인가?
- 가장 쉽게 배우는 도커
- Docker에서 mysql 설치하고 접속하기
- MySQL character set encoding 변경 (utf8, utf8mb4)
- DB - 데이터 타입
- MySQL 데이터형 및 크기
- Mysql 실행하기, DB 리스트 보기, DB 선택, 테이블 보기 명령어 소개
- Import CSV data into MySQL using Node.js
- 랜덤시간소스
- 도커(Docker) 입문편컨테이너 기초부터 서버 배포까지
- 문자열
- [Nodejs] fs (파일 시스템) 읽기, 쓰기, 붙여쓰기, 삭제 등등…
- 대용량 INSERT 처리하기