한 서버에서 여러개의 MariaDB 인스턴스를 동작시키는 방법

[테스트 버전 정보]

  • 서버 : ubuntu 14.04

  • DB : Mariadb : 5.5.64

서버, DB 모두 좀 오래되긴 했지만 문제는 없다.

기본적으로 MariaDB를 구동하면 mysql 기본포트 3306으로 한개의 인스턴스가 동작한다.

vi /etc/mysql/my.cnf 

[mysql]이라는 항목이 있을텐데 [mysql3306]으로 바꿔준다.

앞으로 여러개의 인스턴스를 관리하려면 여러 인스턴스들을 GNR(Group Number)로 관리해줘야 하는데,

config 파일에서 [mysqldGNR] 형식으로 GNR을 정의한다.

이후 새로운 인스턴스의 설정들을 config 파일(my.cnf)에 정의해준다.

나는 3311번 포트를 사용하는 인스턴스를 생성하려고 한다.

config 파일에 새로운 인스턴스(3311번)의 설정들을 정의해주면 mysql_install_db 명령어를 통해 새로운 인스턴스를 설치한다.

 

이후 mysqld_multi start {GNR} 명령어로 새로운 인스턴스(3311번)를 실행한다.

기존의 3306번 서비스이외에 새로 추가한 인스턴스가 3311포트로 새로 동작하는것을 확인할 수 있다.

 

3306 인스턴스
3311 인스턴스

두 인스턴스를 보면 다른 데이터베이스임을 확인할 수 있다.

'데이터베이스' 카테고리의 다른 글

How to create RESTAPI using DreamFactory  (0) 2020.03.23
[Redis] Bloom Filter  (0) 2020.01.31
Database Cache Server  (0) 2020.01.23
[Redis] HyperLogLog  (0) 2020.01.22
[hiredis] Using redis Database in C  (0) 2020.01.17

드림팩토리를 통해 자동으로 RESTAPI를 생성해보자.

[드림팩토리 설치]

드림팩토리를 설치하기 위해 먼저 설치되어야할 소프트웨어들이 있다.

  • PHP 7.2 이상

  • Git

  • 웹서버

  • 데이터베이스(드림팩토리 자체에서 사용할 용도)

  • Composer

https://github.com/dreamfactorysoftware/dreamfactory.git에서 클론을 받는다.

드림 팩토리는 PHP Laraval Framework를 통해 개발된것을 볼 수 있으며 composer를 통해 패키지를 설치해준다.

artisan 커맨드를 통해 드림팩토리에서 사용할 데이터베이스의 정보 및 사용자 정보를 입력한다.

 

RESTAPI에 연결한 DB 정보가 아닌 드림팩토리 자체에서 사용할 DB정보를입력
드림팩토리 계정 정보

환경설정이 완료되었으면 서버를 시작한다.

host 옵션을 주지않으면 디폴트로 127.0.0.1로 서버가 열리는데 내부에서만 접근 가능하므로,

0.0.0.0으로 서버를 열고 방화벽 정책을 통해 화이트리스트 기반으로 접근제어하는게 좋겠다.

드림팩토리를 리눅스에 설치해야하는데 리눅스에서 웹브라우저로 서비스를 이용해도 괜찮다면 127.0.0.1로 열어도 괜찮다.

 

설치가 정상적으로 이루어지면 기존에 생성한 계정을 통해 로그인한다

 

[RESTAPI 만들기]

로그인 후 메인화면

 

먼저 Services 탭에서 서비스를 생성한다.

 

서비스 생성시 Config탭에서 연결할 DB의 정보를 입력한다.

 

이후 해당 서비스에 접근할 권한을 설정하기 위해 role 탭에서 해당 서비스 전용 role을 생성한다.

 

위 세팅은 sakila서비스에 있는 모든 프로시져에 대해 get과 post 메소드만을 허용한다는 의미이다.

 

이제 해당 권한을 적용할 어플리케이션을 Apps 탭에서 생성하고 위에서 생성한 role을 적용한다.

 

어플리케이션을 생성하면 위에서 생성한 서비스에 접근할 수 있는 API Key를 생성해준다.

해당 API Key를 가지고 sakila 서비스에 있는 모든 프로시져에 대해 get과 post 메소드를 통해 접근할 수 있다.

 

Data탭에 sakila 서비스를 선택 후 테이블 목록이 제대로 조회된다면 드림팩토리와 데이터베이스 연결이 제대로 된다는 뜻이다. 

보통은 외부 데이터베이스에서 접근 통제 rule을 설정해서 허용해 주어야 하기 때문에 바로 연결되지 않을것이다.

 

외부 데이터베이스 RESTAPI read용도의 Stored Procedure를 생성해 두었다.

 

해당 프로시저를 실행하면 이렇게 결과를 준다.

 

postman을 통해 헤더에 API Key를 추가하여 API를 호출하면,

Stored Procedure의 결과를 Json형태로 파싱해 response를 받을 수 있다.

 

위 예제에서 https://xxxxxx.apps.dreamfactory.com/api/v2/sakila/_proc/getRental와 같이 드림팩토리의 URL을 사용해야 하는데,

express류의 서버를 포팅서버로 두고 express 내부에서 드림팩토리로 통신하여 

https://test.com/sakila/getRental과 같이 URI를 사용함으로써 리소스를 좀더 명확하게 표기할 수 있다.

 

API Docs

또한 /example/{id} 형태의 가변적인 API가 필요할 경우 드림팩토리 상에서 /_proc/{procedure_name} 형태에

post 메소드를 통해 request를 보내고 id는 body에 포맷에 맞게 붙여주면 된다.

 

RESTAPI의 여러가지 사용법은 위 이미지 처럼 API Docs 형태로 가이드가 존재하니 설명대로 사용하면 되겠다.

 

'데이터베이스' 카테고리의 다른 글

How to run multiple instances of MariaDB  (0) 2020.04.07
[Redis] Bloom Filter  (0) 2020.01.31
Database Cache Server  (0) 2020.01.23
[Redis] HyperLogLog  (0) 2020.01.22
[hiredis] Using redis Database in C  (0) 2020.01.17

[Bloom Filter란]

Bloom Filter는 어떠한 값이 특정 데이터 집합에 속하는지를 판단하는데 사용하는 확률적 자료구조이다.
주로 데이터 집합의 크기가 매우 커서 데이터가 집합에 속해있는지 판단하는데 오래걸리는 경우 Bloom Filter를 사용한다.

  

그러나 언제나 정확한 값을 도출하지는 않는다. false nagative는 없으나 false positive가 발생할 수 있다.
즉, 집합에 속한것이 없는데 있다고 할 수는 있어도 있는걸 없다고 할일은 절대 없기 때문에
Bloom Filter에서 '이거 있어?'에 대한 대답은 '확실히 이건 없어요' 혹은 '있는거 같은데요'만 있다. '이거 있어요!'는 없다.
'있는거 같은데요'의 경우 확실히 있는지 알기위해서는 실제 데이터베이스에 접근하여 데이터 존재 여부를 정확히 판단하면 되므로 전체 시스템 구성에서 오류 발생률은 0%이다. (보통 Bloom Filter는 real DB 앞단에 구성되기때문)

  

Bloom Filter 말고도 Hash Table, AVL Tree, RB tree와 같은 오류 발생률 0%의 자료구조들도 있지만
Bloom Filter를 사용하는 이유는 바로 적은 메모리 사용을 통한 속도향상이다.
그러나 또 다른 특징중 하나는 데이터 집합에 원소를 삭제하는것이 불가능하다는 것이다.

  

Bloom Filter와 같은 용도에 삭제까지 가능한 자료구조가 있다.
바로 Cuckoo Filter라는 확률적 자료구조인데 성능에는 약간 차이가 있다.
Bloom Filter는 원소를 삽입 할 때 성능이 좋기 때문에 데이터 집합에 원소를 자주 추가하는 경우 사용하면 좋다.
반면 Cuckoo Filter는 데이터 조회가 더 빠르며 삭제도 가능하다.

[Bloom Filter 적용 사례]

- Chrome은 악성 URL을 확인하기위해 사용.
- Medium은 기사가 이미 유저에게 추천되었는지 확인하기위해 사용.
- Ethereum Blockchain 로그를 빠르게 찾기위해 사용.
- PostgreSQL과 Google Bigtable은 존재하지 않는 튜플 또는 컬럼을 찾는데 디스크 탐색을 줄이기 위해 사용.

[Redis에 Bloom Filter 설치]

Redis에서 BloomFilter는 기본적으로 내장된 자료구조가 아니다.

때문에 모듈을 redis server에 로드해서 사용해야한다.

RedisBloom 모듈의 소스코드를 다운받는다.
빌드하면 so 파일이 생성된다.
 /etc/redis/redis.conf 파일에 RedisBloom 모듈을 추가해준다.
서비스를 재시작한다.

RedisBloom 모듈은 여러 자료구조를 지원한다.

  • Bloom Filter

  • Cuckoo Filter

  • Count-Min Sketch

  • Top-K

[Bloom Filter 사용법]

  • BF.RESERVE : 빈 key를 생성하며 false positive 발생률, 원소의 갯수 등 옵션을 설정할 수 있다.
    포맷 - BF.RESERVE {key} {error_rate} {capacity} [EXPANSION expansion] [NONSCALING]

    key [필수] : 키 이름 설정  
    error_rate [필수] : false positive 발생률을 설정하며 인자 1을 100%로 기준삼아 0.1을 주면 10%이고 0.001을 주면 false positive 발생률 0.1%을 의미한다.  
    capacity [필수] : 최대 원소의 갯수를 설정하며 이 기준을 초과할 때 성능은 하락할 수 있다.  
    expansion [옵션] : 최대 원소의 갯수 초과시 몇개의 원소를 추가로 받을지 설정하는 옵션  
    NONSCALING [옵션] : 최대 원소의 갯수 초과시 추가 원소를 받지 않는다는 옵션  
    집합 false positive 최대 원소의 갯수 추가원소 허용
    BlackList 0.1% 50000 불가능
    WhiteList 1% 30000 5000
  • BF.ADD : key에 원소를 추가하며 없는 key라면 생성후 추가한다.
    포맷 - BF.ADD {key} {item}

      key [필수] : 키 이름 설정
      item [필수] : 삽입 할 원소
  • BF.MADD : BF.ADD와 같으며 다량의 원소를 한번에 추가할 수 있다.
    포맷 - BF.ADD {key} {item} [item] [item] [item]

  • BF.INSERT : BF.RESERVE와 BF.ADD를 합친것과 같다.
    포맷 - BF.INSERT {key} [CAPACITY {cap}] [ERROR {error}] [EXPANSION {expansion}] [NOCREATE] [NONSCALING] ITEMS {item...}

      key [필수] : 키 이름 설정
      cap [옵션] : 최대 원소의 갯수를 설정하며 이 기준을 초과할 때 성능은 하락할 수 있다.
      error [옵션] : false positive 발생률을 설정하며 인자 1을 100%로 기준삼아 0.1을 주면 10%이고 0.001을 주면 false positive 발생률 0.1%을 의미한다.
      expansion [옵션] : 최대 원소의 갯수 초과시 몇개의 원소를 추가로 받을지 설정하는 옵션
      NOCREATE [옵션] : 키가 존재하지 않는경우 키를 생성하지 않는다는 옵션
      NONSCALING [옵션] : 최대 원소의 갯수 초과시 추가 원소를 받지 않는다는 옵션
      item [필수] : 삽입 할 원소
  • BF.EXISTS : 데이터 집합안에 해당 원소가 들어있는지 확인한다.
    포맷 - BF.EXISTS {key} {item}

      key [필수] : 키 이름 설정
      item [필수] : 삽입 할 원소
    존재하는것 같으면 1, 존재하지 않으면 0을 반환
  • BF.MEXISTS : BF.EXISTS와 같으며 다량의 원소를 한번에 조회할 수 있다.
    포맷 - BF.EXISTS {key} {item} [item] [item] [item

* https://github.com/RedisBloom/RedisBloom/blob/master/docs/Bloom_Commands.md

'데이터베이스' 카테고리의 다른 글

How to run multiple instances of MariaDB  (0) 2020.04.07
How to create RESTAPI using DreamFactory  (0) 2020.03.23
Database Cache Server  (0) 2020.01.23
[Redis] HyperLogLog  (0) 2020.01.22
[hiredis] Using redis Database in C  (0) 2020.01.17

[RDBMS의 문제점]
서버를 구성할 때 데이터베이스는 주로 RDBMS를 사용해 운영한다.
서버의 용도에 따라 다르겠지만 구글이나 네이버 같은 매우 많은 사람들이 사용하는 규모가 된다면
데이터베이스도 포화상태가 될 것이고 쿼리를 하나 실행하는 데에도 많은 시간이 들어갈 것이다.
실제로 공공데이터 포탈에서 2000만 Cardinality 규모의 데이터를 받아 샘플 DB를 생성하고 조회해보면 Index를 걸어놓았음에도 불구하고 20초가 넘게 걸린다.
간단한 조회 쿼리가 아니라 다양한 조건이 걸리고 몇 개의 테이블이 조인되면 더 오래 걸릴 것이다.

 


[데이터베이스 데이터 캐싱]
DB를 튜닝하고 다원화하고 좀 더 효율적으로 인덱스를 걸 수도 있겠지만 가장 근본적인 문제인 RDBMS로의 쿼리 전송을 줄이는 방법도 있을 수 있는데 데이터 캐싱을 통해 어느 정도 쿼리 전송을 줄일 수 있겠다.
데이터베이스에서의 데이터 캐싱이란 처음 쿼리를 전송할 때는 데이터베이스에서 직접 가져오지만 두 번째 쿼리부터는 캐시에 저장된 데이터를 가져와 데이터베이스까지 직접 쿼리를 전송하지 않아도 된다.

 

주로 데이터베이스에서 캐시용으로 NoSQL 류의 Redis나 Memcached를 사용한다.
두 DB 모두 디스크 기반이었던 기존의 RDBMS 들과 달리 메모리 기반이며 성능을 목적으로 개발되었기 때문에 캐시 서버로 주로 사용된다.
(메모리 캐시라는 공통점 이외에는 다른 점이 더 많은 Redis와 Memcached이다.)
가장 기본적이고 단순한 Key-Value 형태로 메모리에 저장하고
또한 내부적으로도 성능에 목적을 둔 기능들이 많기 때문에 데이터 캐시 서버로 사용하기 매우 좋다.

 

메모리 캐시는 잘못 사용하면 성능이 더 안 좋아질 수도 있다고 한다.
보통 캐시에 들어갈 데이터는 자주 사용하는 데이터 위주로 저장해야 하고,
읽기는 많지만 쓰기는 적은 데이터 그리고 데이터의 양이 많지 않은 데이터를 캐싱 하는 것이 적합하다고 한다.
또한 캐시에도 데이터가 쌓이면 언젠가는 RDBMS와 다를 게 없어지므로 적절한 데이터 캐시 만료 기간을 설정해야 한다.

 

 

[데이터 캐싱이 적용된 시스템에서 CRUD]

캐시 서버가 사용되는 데이터베이스 시스템 구성도는 시스템 상황, 용도, 설계자의 캐싱 전력에 따라 달라질 수 있고 매우 다양하게 구성될 수 있으나 나는 가장 기본적인 개념을 설명하기 위해 DB 서버와 캐싱 서버 하나만 둔다.
(캐싱 전략에도 방법론이 있고 공부할게 많다.)

- Read

캐시 서버에 데이터가 없는경우
캐시서버에 데이터가 있는경우

 

- Create : Database에 데이터를 생성한다.

- Update : Datebase에 데이터를 수정하고 캐시서버에도 데이터가 있다면 마찬가지로 수정한다.

- Delete : Database에 데이터를 삭제하고 캐시서버에도 데이터가 있다면 마찬가지로 삭제한다.

 

 

 

물론 캐싱이 만능은 아닐 것이다. 비용도 비용이지만, 제대로 사용하지 못하면, 최신으로 업데이트되지 않은 “틀린” 데이터를 클라이언트에게 제공할 수도 있고 비용이 최적화되지 않을 수도 있다.
가장 중요한 건 기존의 시스템에 정확히 어떤 부분에서 성능이 저하되는지를 주안점으로 두고 그에 대한 대처를 가장 효율적으로 하는 것이 좋지 않을까 싶다.

'데이터베이스' 카테고리의 다른 글

How to create RESTAPI using DreamFactory  (0) 2020.03.23
[Redis] Bloom Filter  (0) 2020.01.31
[Redis] HyperLogLog  (0) 2020.01.22
[hiredis] Using redis Database in C  (0) 2020.01.17
Can't connect to MySQL server on 'address' (10061)'  (0) 2020.01.16

[HyperLogLog란]

HyperLogLog(hll)은 간단히 말하면 중복제거된 값을 매우 적은비용과 매우 빠른 속도로 계산하는데 사용하는 확률적 자료구조이다.

대용량의 데이터에서 중복제거된 unique value을 계산하는데 의미가 있으며 적은 메모리로 정확하지는 않지만 최소한의 오차율을 통해 unique value를 계산한다.

예를들어 포털 사이트에 방문한 사람의 수를 구하는데 또는 포털 사이트에서 하루에 검색한 검색어의 수를 구하는데 사용된다.

물론 집합이나 다른 자료구조를 통해 구할 수 있겠지만 데이터의 크기가 커질수록 엄청난 시간복잡도가 요구될것이다.

 

메모리 기반의 Redis에서 unique value를 찾으려고 하면 용량이 커질수록 메모리는 한정적이기 때문에 한계가 있었다.

 

hll은 이러한 문제를 아주 적은 메모리와 아주 적은 오차율을 통해 해결한다고한다.

참고로 1.5KB의 메모리에는 실제 키를 저장하는데 사용된 메모리는 포함되지 않는다.

 

redis에서 hll은 별도의 자료구조를 사용하지 않으며 raw한 스트링을 사용하며 스트링은 hll자료구조로 이루어져있다고 한다.

또한 unique value를 저장하고있지 않으며 때문에 unique value들을 추가하면 value를 확인할 수 없다.

대용량의 디스크가 또한 필요하지 않다.

 

[HyperLogLog 사용법]

- PFADD 

시간복잡도 O(1)

IP라는 Key에 ip 원소들을 추가한다.

Key에 unique한 원소가 추가되었다면 1이 반환되고 unique하지 않다면 0이 반환된다.

unique하지 않을경우 아무일도 일어나지 않는다.

 

 

- PFCOUNT

시간복잡도 O(1)

IP라는 Key에 있는 원소의 수를 출력한다.

 

 

-PFMERGE

시간복잡도 O(N)

두개 이상의 Key를 하나로 병합한다.

'데이터베이스' 카테고리의 다른 글

[Redis] Bloom Filter  (0) 2020.01.31
Database Cache Server  (0) 2020.01.23
[hiredis] Using redis Database in C  (0) 2020.01.17
Can't connect to MySQL server on 'address' (10061)'  (0) 2020.01.16
How To Use UDF In MySQL  (0) 2020.01.06

[redis]

redis는 디스크가 아닌 메모리 기반 NoSQL로 굉장한 성능을 자랑하는 데이터베이스다.

 

[redis 라이브러리 다운]

 

[소스코드]

 

[컴파일]

gcc 컴파일시 -lhiredis 옵션을 붙여줘야한다.

 

 

[결과]

 

* https://redis.io/clients

'데이터베이스' 카테고리의 다른 글

[Redis] Bloom Filter  (0) 2020.01.31
Database Cache Server  (0) 2020.01.23
[Redis] HyperLogLog  (0) 2020.01.22
Can't connect to MySQL server on 'address' (10061)'  (0) 2020.01.16
How To Use UDF In MySQL  (0) 2020.01.06

외부에서 DB에 접근하려고 할 때 에러가 발생한다.

 

DB는 MariaDB 10.1.43기준이다.

 

/etc/mysql/mariadb.conf.d 디렉토리에 50-server.cnf 파일을 편집기로 오픈한다.

 

29번째 라인을 주석처리한다.

 

DB를 재구동한다.
정상적으로 접근이 되는것을 확인할 수 있다.

 

'데이터베이스' 카테고리의 다른 글

[Redis] Bloom Filter  (0) 2020.01.31
Database Cache Server  (0) 2020.01.23
[Redis] HyperLogLog  (0) 2020.01.22
[hiredis] Using redis Database in C  (0) 2020.01.17
How To Use UDF In MySQL  (0) 2020.01.06

[MySQL 라이브러리다운]
apt-get install libmysqlclient-dev

[다운 후 라이브러리의 위치를 찾는다.]

해당 경로에 mysql.h가 설치되었다.


[so파일 소스코드]

문자열에 있는 알파벳 대문자의 갯수를 반환하는 함수 작성(Non Aggregate)

* UDF 작성 공식 문서(https://mariadb.com/kb/en/creating-user-defined-functions/)


[so파일 생성]

so파일 생성 후 plugin 디렉토리로 복사
get plugin directory 

 

[MySQL에서 UDF 정의 및 사용] 

 

 

* 참고 : 윈도우에서 작업할 때 mysql.h위치는 mysql 설치 경로에 include 폴더이고,

           DLL은 설치경로에 lib/plugin 폴더에 위치시키면 된다.

mysql.h 경로
DLL 경로

 

'데이터베이스' 카테고리의 다른 글

[Redis] Bloom Filter  (0) 2020.01.31
Database Cache Server  (0) 2020.01.23
[Redis] HyperLogLog  (0) 2020.01.22
[hiredis] Using redis Database in C  (0) 2020.01.17
Can't connect to MySQL server on 'address' (10061)'  (0) 2020.01.16

+ Recent posts