MogileFS는 Hadoop DFS(큰 사이즈에 적합)와 달리, 소규모 용량에 적합하게 설계되어 있다. 멀티미디어(이미지 혹은 소규모 동영상 파일) 파일 서비스에 유용할 것 같아서 전체 구조와 프로세스, 설치하면서 아키텍처의 이해도를 높이는 데 목표를 두고 정리한다.
MogileFS Overview
1. 개요
-
Application Level
- 특별한 커널 모듈은 필요하지 않다.
-
No SPOF(single point of failure)
- 세 개의 컴포넌트들(Storage Nodes, Trackers, Tracker’s DB(s))은 복수 개의 머신에서 수행될 수 있으므로, SPOF는 없다.
- Tracker는 Storage Node와 같은 머신에서 실행할 수 있어, 최소 2개의 머신이 권장된다.
-
Automatic File Replication
- 파일들은 그들의 ‘class’에 따라 각기 다른 Storage Node에 자동적으로 replicate된다. 또한, 자동으로 복제될 때마다 카운트를 하고 최소 카운트를 만족하는 충분한 용량을 가진 스토리지 노드로 복제된다.
- 예를 들어 포토 호스팅 서비스라면, 원본 JPEG는 최소 리플리카를 3으로, 썸네일 및 크기가 조절된 버전들은 1 또는 2로 설정할 수 있다.
- 이러한 방식으로, RAID를 사용하지 않고 불필요한 데이터를 복수 개 저장하지 않고 비용을 절감할 수 있다.
-
Better than RAID
- non-SAN RAID 설정에서는 디스크는 중복되지만 호스트는 중복되지 않는다. 따라서 전체 머신이 고장나면 파일들은 접근할 수 없게 된다.
- MogileFS는 서로 다른 호스트상의 장치들 간의 파일들도 replicate하기 때문에 파일들은 항상 접근 가 능하다.
-
Flat Namespace
- 파일들은 flat하고 전역적인 네임스페이스 안의 이름을 가진 키로서 식별된다.
- 네임스페이스는 얼마든지 많이 만들 수 있기 때문에, 잠재적으로 키들이 충돌하는 여러 개의 애플리케이션들이 하나의 MogileFS 설치상에서 실행될 수 있다.
-
Shared-Nothing
- MogileFS는 공유된 디스크들로 비싼 SAN에 의존하지 않는다. 모든 머신들은 자신의 로컬 디스크를 가진다.
-
No RAID required
- MogileFS Storage Node들의 로컬 디스크들은 RAID로 구성하든, 하지 않든 상관없다. MogileFS가 지원하지 않는 안정성을 위해 RAID를 구성하지 않아도 된다. 구성하지 않으면 보다 저렴하다.
-
Local filesystem agnostic
- MogileFS Storage Node상의 로컬 디스크들은 다양한 형태의 파일시스템(ext3, XFS 등)을 선택할 수 있다.
- MogileFS는 자신의 내부 디렉토리 해싱을 하므로 “디렉토리당 최대 파일”, 혹은 “디렉토리당 최대 디렉토리” 등의 파일시스템 제한과 무관하다.
2. 지원하지 않는 것들
-
POSIX Compliant
- MogileFS를 대상으로 보통의 유닉스 애플리케이션이나 DB를 실행할 수 없다. 이것은 한 번 쓰는 파일을 아카이빙하고 계속해서 읽기만 하는 것을 의 미한다.(파일의 수정은 새로운 버전의 파일로 덮어쓰기 하는 것으로 가능하기는 하다.)
- 파일들을 저장하고 회수하기 위해서는 애플리케이션들이 MogileFS 클라이언트 라이브러리를 사용해야 한다. 보통 다음과 같은 과정을 밟는다:
- Tracker에게 넣고 싶은 것과 얻고 싶은 것에 대해 알려준다.
- 애플리케이션이 파일을 읽거나 쓸 수 있다고 Tracker가 알려주는 장소들 중 하나에 HTTP GET/PUT을 사용하여 파일을 읽거나 쓴다.
- FUSE binding을 프로토타이핑해 두어 MogileFS를 애플리케이션 지원 없이 사용할 수도 있지만, 제품 수준으로 준비된 것은 아니라고 한다.
-
Completely portable … yet
- 코드에 어느 정도 Linux-isms이 있는데, 특히 HTTP 전송 코드가 그렇다. 이것을 걷어내고 portable하게 만들 계획이라고 한다.
3. High-level overview of MogileFS
-
The involved parties are
- Application : 파일을 저장하고 로드하려는 주체.
- Tracker (the mogilefsd process) : 애플리케이션에서의 모든 클라이언트 커뮤니케이션을 관리하는 이벤트 기반의 부모 프로세스/메시지 버스. mogilefsd 자식 프로세스와의 커뮤니케이션 핸들링과 그러한 요청들에 대한 “query workers”를 로드밸런싱하며, HA를 위해서는 서로 다른 호스트에서 2개의, 로드밸런싱을 위해서는 그 이상의 tracker를 실행해야 한다. mogilefsd 하의 자식 프로세스들 은 다음 작업을 수행한다.
- Replication : 파일의 리플리케이션.
- Deletion : 네임스페이스에서의 삭제는 즉각적이며, 파일시스템에서의 삭제는 비동기적이다.
- Query : 클라이언트의 요청에 응답.
- Reaper : 디스크 처리 실패 후 리플리케이션을 위해 파일 재 큐잉.
- Monitor : 호스트와 장치들의 안정성 및 상태 모니터링.
- Database : MogileFS의 메타데이터(네임스페이스, 어떤 파일이 어디에 있는가 등)를 저장하는 DB. HA 설정 내에 들어있어야 하므로 SPOF가 없다.
- Storage Nodes : 파일들이 저장되는 곳. DELETE, PUT 등이 수행되는 HTTP 서버들. WebDAV 서버들도 좋지만, mogstored가 권장된다. mogilefsd는 서로 다른 포트에 두 개의 서버를 사용하도록 설정될 수 있고 모든 DAV 오퍼레이션(및 sideband 모니터링)에 mogstored를 사용하고, GET 오퍼레이션에 빠르고 가벼운 HTTP 서버를 선택해서 사용할 수 있다. 보통은 마운트 지점당 하나의 fat SATA 디스크를 가진다. 각 디스크는 /var/mogdata/devNN에 마운트된다.
-
High-level flow:
- 애플리케이션이 파일 열기를 요청. Tracker로의 라이브러리를 통해, 이용 가능한 것 아무에게나 RPC를 통해 요청. create_open 요청.
- Tracker는 요청이 갈 수 있는 곳에 대해 로드밸런싱 판단을 하고, 애플리케이션에 가능한 몇 개의 위치를 알려준다.
- 애플리케이션은 그 중 하나의 위치에 쓰기를 실행한다. 도중에 쓰기에 실패하면 또 다른 곳에 쓰기를 재시도할 수 있다.
- 애플리케이션(클라이언트)은 create_close API 안에, 어디에 쓰기를 수행했는지를 Tracker에게 알려준다.
- Tracker는 그 이름을 도메인의 네임스페이스에 DB를 통해 링크한다.
- Tracker는 그 파일이 속한 클래스의 리플리케이션 정책에 부합될 때까지 백그라운드로 리플리케이션을 시작한다.
- 이후 애플리케이션이 그 도메인+키(키는 파일이름)에 대해 get_paths 요청을 발행하면, Tracker는 database/memcache/etc에 물어본 다음 해당 파일이 접근할 수 있는 모든 URL을 응답해 준다. 각 위치에서 I/O 활용도에 기반하여 비중이 정해진다.
- 애플리케이션은 그 URL들을 순서대로 시도해 본다. Tracker는 지속적으로 모든 호스트와 장치들을 모니터링하기 때문에 죽은 대상을 반환하지 않고, 디폴트로 반환된 리스트 안의 첫번째 아이템이 존재하는지를 두 번 체크한다.
4. 논리적 구조
-
domain
- 파일의 최고 수준 분리. 파일 키는 도메인 안에서 유니크하다.
- 도메인은 도메인 내의 파일들을 정의하는 클래스들의 집합으로 구성된다.
- 예) fotobilder, livejournal
-
class
- 각각의 파일은 정확히 하나의 클래스에 속한다.
- 클래스는 하나의 도메인의 일부이다.
- 클래스는 파일 하나의 최소 리플리카 수를 지정한다.
- 예) userpicture, userbackup, phonepost.
- 클래스는 추가적인 replication 정책을 가질 수 있다.
-
key
- 파일을 식별하는 유니크한 문자열.
- 키들은 도메인 내에서 유니크하다.
- 예) userpicture:34:39, phonepost:93:3834, userbackup:15.
- 가짜 구조도 사용할 수 있다.
-
minimum replica count (mindevcount)
- 클래스가 가지는 프로퍼티로서 어떤 클래스에 속하는 파일들이 서로 다른 장치들에 몇 번이나 복제되어야 하는지를 나타내는 수.
-
file
- 파일은 MogileFS에 업로드하는 bit들의 컬렉션을 말하며, 파일들은 최소 복제 카운트(mindevcount)에 따라 복제된다. 각 파일들은 키를 가지며, 클래스의 한 부분이고 하나의 도메인에 위치한다.
-
fid
- 파일의 내부적인 수치적 표현. 모든 파일은 유니크한 fid를 가진다. 파일이 덮어쓰기 되면 새로운 fid를 받는다.
MogileFS 설치
1. MogileFS Architecture
2. 호스트
192.168.1.1 mimul1 - Tracker Server
192.168.1.2 mimul2 - Storage Server
192.168.1.3 mimul3 - mysql3. 서버 정보
- OS : Centos 5.7 x86_64
- Perl : v5.8.8
4. 설치
> yum -y install perl-libwww-perl- cpan 설치 - 지역 선택 이외엔 디폴트(Asia/Korea)
> cpan 엔터
>- Perl 라이브러리 설치
cpan> install Net::Netmask
cpan> install Danga::Socket
cpan> install IO::AIO #Linux::AIO
cpan> install Perlbal
cpan> install MogileFS::Client
cpan> install DBI
cpan> install DBD::mysql
cpan> exit- MogileFS 라이브러리 설치
> wget http://cpan.sarang.net/authors/id/D/DO/DORMANDO/MogileFS-Server-2.55.tar.gz
> tar xvfz MogileFS-Server-2.55.tar.gz
> cd MogileFS-Server-2.55
> perl Makefile.PL
> make
> make install
> wget http://cpan.sarang.net/authors/id/D/DO/DORMANDO/MogileFS-Utils-2.21.tar.gz
> tar xvfz MogileFS-Utils-2.21.tar.gz
> cd MogileFS-Utils-2.21
> perl Makefile.PL
> make
> make install- 데이터베이스 계정 및 스키마 생성(mimul3) : 파일의 메타정보를 MySQL에 저장 관리된다.
mysql> create database mogilefs;
mysql> grant all on mogilefs.* to 'mogile'@'%' identified by 'mogileadmin';
mysql> flush privileges;- DB 스키마 설정(mysql)
> mogdbsetup --dbhost=192.168.1.3 --dbname=mogilefs --dbuser=mogile --dbpassword=mogileadmin5. Tracker/Storage 서버 설정
- 두 서버에 /etc/security/limits.conf 수정
user soft nofile 65536
user hard nofile 65536- Tracker Server(mimul1)
> groupadd mogile
> useradd -g mogile mogile
> mkdir -p /etc/mogilefs
> cd /etc/mogilefs
> wget http://code.sixapart.com/svn/mogilefs/tags/mogilefs-server-2.37/conf/mogilefsd.conf
> mkdir -p /var/mogdata
> cat mogilefsd.conf
daemonize = 1
# Database connection information
db_dsn = DBI:mysql:mogilefs:host=192.168.1.3
db_user = mogile
db_pass = mogileadmin
> sudo -u mogile mogilefsd -c /etc/mogilefs/mogilefsd.conf --daemon # Daemon 구동- Storage Server(mimul2)
> groupadd mogile
> useradd -g mogile mogile
> chown -R mogile:mogile /var/mogdata
> mkdir -p /etc/mogilefs
> cd /etc/mogilefs
> wget http://code.sixapart.com/svn/mogilefs/tags/mogilefs-server-2.37/conf/mogstored.conf
> mkdir -p /var/mogdata
> cat mogstored.conf
maxconns = 10000
httplisten = 0.0.0.0:7500
mgmtlisten = 0.0.0.0:7501
docroot = /var/mogdata
> mkdir -p /var/mogdata/dev1
> mkdir -p /var/mogdata/dev2
> chown -R mogile:mogile /var/mogdata/*
> mogstored --daemon #Daemon 구동6. host, device, domain, class 등록
- Tracker Server(mimul1)
> mogadm check
Checking trackers...
127.0.0.1:7001 ... OK
Checking hosts...
No devices found on tracker(s).
> mogadm host add 192.168.1.2 --port=7500
> mogadm check
Checking trackers...
127.0.0.1:7001 ... OK
Checking hosts...
[ 1] 192.168.1.2 ... skipping; status = down
No devices found on tracker(s).
> mogadm device add 192.168.1.2 1
> mogadm device add 192.168.1.2 2
> mogadm host mark 192.168.1.2 alive
> mogadm check
Checking trackers...
127.0.0.1:7001 ... OK
Checking hosts...
[ 1] 192.168.1.2 ... OK
Checking devices...
host device size(G) used(G) free(G) use% ob state I/O%
---- ------ ------- -------- -------- ------ ---------- -----
[1] dev1 26.109 4.571 21.538 17.51% writeable 0.0
[1] dev2 26.109 4.571 21.538 17.51% writeable 0.0
---- ------ ------- -------- -------- ------
total: 52.219 9.143 43.076 17.51%
> mogadm host list
192.168.1.2 [1]: alive
IP: 192.168.1.2:7500
> mogadm device list
192.168.1.2 [1]: alive
used(G) free(G) total(G)
dev1: alive 4.571 21.537 26.108
dev2: alive 4.571 21.537 26.108
> mogadm domain add mimul
> mogadm class add mimul normal --mindevcount=2
> mogadm domain list
domain class mindevcount replpolicy
---------- --------- ------------- ------------
mimul normal 2 MultipleHosts()7. 파일 업로드 테스트
- 커맨드 실행 결과
> mogtool --trackers=127.0.0.1:7001 --domain=mimul --class=normal inject --nobigfile /root/mogail_test.txt test1
Upload so far: 14 bytes [100.00% complete]
> mogtool --trackers=127.0.0.1:7001 --domain=mimul --class=normal extract test1 /root/mogail_return.txt
Fetching piece 1...
Trying http://192.168.1.2:7500/dev2/0/000/000/0000000008.fid...
Done.- Perl 클라이언트 실행 결과
#!/usr/bin/perl
use strict;
use warnings;
use MogileFS::Client;
my $mogfs = MogileFS::Client->new(
domain => 'mimul',
hosts => [ '192.168.1.1:7001' ],
);
die "Unable to initialize MogileFS object." unless $mogfs;
my $key = "hello";
my $class = "normal";
my $fh = $mogfs->new_file($key, $class) or die $mogfs->errstr;
my $file_contents = "Hello, MogileFS!!";
$fh->print($file_contents) or die $mogfs->errstr;
$fh->close or die $mogfs->errstr;
my $data = $mogfs->get_file_data($key);
die $mogfs->errstr unless $data;
print $$data . "\n";8. MogileFS 내부의 파일 노드 관리
-
MogileFS 내부적으로 관리되는 VFS에서 파일의 확장자는 .fid다. 초기 설정 시 만든 mindevcount = 2 normal class를 지정했기 때문에 dev1, dev2 두 개의 device에 복사된다. 복사되는 device는 사용 가능한 것(status = alive) 중에서 무작위로 선택된다.
-
물리 파일 정보
> ls /var/mogdata/**/**/**/**/*.fid
/var/mogdata/dev1/0/000/000/0000000008.fid
/var/mogdata/dev2/0/000/000/0000000008.fid- 메타 정보 : MogileFS에서 파일을 fid라는 id로 관리하고 file 테이블에 파일의 key와 class를 저장하고 있으며, file_on 테이블에서 파일이 어떤 device에 복사되고 있는지를 관리한다.
mysql> select * from file;
+-----+------+-------+--------+---------+----------+
| fid | dmid | dkey | length | classid | devcount |
+-----+------+-------+--------+---------+----------+
| 8 | 1 | test1 | 14 | 1 | 2 |
+-----+------+-------+--------+---------+----------+
mysql> select * from file_on;
+-----+-------+
| fid | devid |
+-----+-------+
| 8 | 1 |
| 8 | 2 |
+-----+-------+
mysql> select * from device;
+-------+--------+--------+--------+----------+---------+------------+
| devid | hostid | status | weight | mb_total | mb_used | mb_asof |
+-------+--------+--------+--------+----------+---------+------------+
| 1 | 1 | alive | 100 | 26735 | 4682 | 1324887639 |
| 2 | 1 | alive | 100 | 26735 | 4682 | 1324887639 |
+-------+--------+--------+--------+----------+---------+------------+
mysql> select * from host;
+------+------+--------+------------+--------+-----------+-------+-------+
|hostid|status|http_port|http_get_port|hostname|hostip | altip |altmask|
+------+------+--------+------------+--------+-----------+-------+-------+
| 1 |alive | 7500 | NULL |192.168.1.2|192.168.1.2|NULL|NULL |
+------+------+--------+------------+-----------+-----------+----+-------+
1 row in set (0.00 sec)- DB 정보의 device, host 정보를 가지고 파일의 URL을 조립할 수 있다.
- key에서 fid를 취득 (file 테이블) → /0/000/000/0000000008.fid 결정
- fid에서 device id를 취득 (file_on 테이블) → /dev1, /dev2 결정
- device id에서 host id를 취득(device 테이블)
- host id에서 host 정보를 취득 (host 테이블) → http://192.168.1.2:7500 결정
- 최종 URL: http://192.168.1.2:7500/dev1/0/000/000/0000000008.fid, http://192.168.1.2:7500/dev2/0/000/000/0000000008.fid
MogileFS 활용 사례
주로 이미지, 음악, 비디오, 사용자가 올린 파일들을 저장하는 저장소로 활용된다. MogileFS는 소규모 파일 분산 저장소로 각광받고 있으며 다음과 같은 서비스에서 사용된다.
- last.fm, SixApart, TypePad, Vox, YellowBot, Wikispaces, Footnote, KWICK! Community, livejournal, hatena, SugarSync
참조 사이트
MogileFS는 SPOF 없는 아키텍처와 자동 파일 복제 기능으로 소규모 분산 파일 서비스에 실용적인 선택지다. Hadoop DFS처럼 대용량 처리보다는 이미지·동영상 같은 소규모 파일의 안정적 서빙에 강점이 있으며, 설치와 운영이 비교적 단순한 편이다.

