0. 실황
모니터링 툴에 사용되는 DB로써 모니터링되는 대상의 값들을 주기적으로
테이블에 저장합니다.(1분에 몇백~몇천껀씩 INSERT)
1.테이블 구조
RefIndex(int)/ Time(varchar(30)) / Value(float) 의 구조로 되어있습니다.
이 구조의 테이블이 하루에 하나씩(날짜기준으로) 생성됩니다.
RefIndex와 Time은 복합으로 인덱싱되어있습니다.
Time은 yyyy-mm-dd hh:mm:ss 로 저장
2. 데이터
하루에 150만건(레코드) 정도의 데이터가 테이블에 저장됩니다.
테이블용량은 120~130MB정도 됩니다.(인덱스 용량은 테이블용량의 80%정도)
3. 조회(쿼리)
자주 사용하는 쿼리는
a. "오늘테이블"에서 "지금부터" ~ "1시간전" 데이터 조회
ex : select * from $today where RefIndex=100 and ( Time < "지금부터" AND Time > "1시간전" ) order by Time;
b. "오늘테이블"에서 "0시부터" ~ "24시" 데이터 조회
c. 한달간 데이터 조회
ex : select * from $today where RefIndex=100 UNION ... UNION .. select * from $today-30 where RefIndex = 100 order by Time
4. 문제
a. "오늘테이블"은 INSERT가 빈번하게 발생하여 오늘 데이터 조회시 테이블 캐싱이 되지않아 쿼리 속도가 현저히 저하
b. 한달간 데이터 조회는 방대한양(?)의 조회에 의한 쿼리 속도 저하(UNION, Order by구문)
c. explain 명령으로 보면 인덱싱은 하고 있음.
d. RefIndex가 바뀌는 경우가 빈번하여 쿼리자체가 변경되어 쿼리 캐싱은 기대하지 못함.
5. 해결방향
a. 명시적으로 테이블을 메모리에 캐싱한 뒤 지속적으로 메모리에 적재되도록 설정
- Mysql 설정 방법을 찾지 못함
b. INSERT가 되더라도 전체를 캐싱하지 않고 추가 부분만 메모리와 동기화 시키는 방법 모색
- DB 설정으로 가능한지 파악하지 못함
c. DB가 셧다운되는 상황이 발생되어도 데이터는 안전해야함.(Heap 엔진을 사용못함)
d. 최악의 경우 Thread를 돌려 Select * from $today 를 반복적으로 수행하여 캐싱 보장
6. 참고 사항
a. 170만건 풀스캔시 50초, 캐싱뒤 2초->0.22초->0.00초 쿼리 소요됨
a-1. InnoDB 사용
b. 서버 사양 : OS WindowServer CPU 1.6Ghz Mem : 1Gb Disk: 40Gb 7200rpm(테스트 PC)
c. 주가를 모니터링하는 APP에서 Mysql이 적용된 사례는 없는지 확인중..
실시간성과 방대한 데이터가 비슷한 특징
쿼리의 속도 저하문제를 메모리의 캐싱 방법으로 해결하려고 합니다.
(방법이 있다면 메모리가아닌 다른 방법도 상관없음)
혹시 이런 경험이 있어 해결방법을 알고 계시거나
유용한 TIP이 있으신분은 알려주시면 감사하겠습니다.
ps - 현재 메모리에 캐싱된 테이블(혹은 쿼리) 리스트를 볼 수 있는 명령 좀 알려주세요 |