紹介
株式会社ネクスト 金融グループでシステムエンジニアとして勤務している金成奉です。
近年多くの企業が、POI (Point of Interest、位置情報) やGIS関連データ(区画ポリゴン、道路のラインなど)を扱うようになりました。
GIS関連データを扱う際、システムエンジニアが最初に接するのが、空間データベースです。
何年か前からGIS関連オープンソースは、UbuntuOSに最適化され、世界の開発者達もUbuntuOSを利用する傾向が強くなり、日本の企業で一番多く使われているCentOSでは、コンパイル構築すら難しくなりました。
そのため、CentOSでオープンソースを利用して空間データベースを構築する方法を簡単に紹介致します。
最新バージョンのCentOS及びオープンソースを利用して、PostGIS及びpgRouting(ルート検索機能)を構築します。
構築概要
CentOSがインストールされているVPSまた実機での構築となります。
用途としては空間データベース専用マシーンを前提としています。
コンパイルの設定オプションは、「--prefix=/usr」としているため、「/usr/local」などのディレクトリにインストールする際は、オプションを適宜変更してください。
Linuxバージョン確認
#Linuxバージョン確認
cat /proc/version
Linux version 2.6.32-431.3.1.el6.x86_64 (mockbuild@c6b10.bsys.dev.centos.org) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) ) #1 SMP Fri Jan 3 21:39:27 UTC 2014
OSバージョンの確認
#OSバージョン確認
cat /etc/redhat-release
CentOS release 6.5 (Final)
ユーザー確認
cat /etc/passwd
useradd potgres
OpenSSLバージョン(HeartBleedセキュリティ確認)
openssl version
OpenSSL 1.0.1e-fips 11 Feb 2013
以下のバージョンであれば、安全(最後が5.7以上)
openssl.x86_64 1.0.1e-16.el6_5.7
基本アップデート実行
#アップデートを行い、OSを最新の状態にする。 yum install yum-fastestmirror #アップデートパッケージをチェックする #すべてアップデートするか、チェックしたリストを選んで個別にアップデートする。 yum check-update #構わずアップデートを行う。 yum update
コンパイル環境構築
#基本コンパイル環境インストール yum -y install autoconf yum -y install automake yum -y install libtool.x86_64 yum -y install flex.x86_64 yum -y install bison.x86_64 yum -y install gcc.x86_64 yum -y install gcc-c++.x86_64 yum -y install make.x86_64 yum -y install kernel-headers.x86_64 yum -y install kernel-devel.x86_64
#最新GISサポートPostgreSQL-9.3.4コンパイル環境構築
yum -y install subversion.x86_64 yum -y install libxml2-devel.x86_64 yum -y install json-c-devel.x86_64 yum -y install openssl-devel.x86_64 yum -y install readline-devel.x86_64 yum -y install zlib-devel.x86_64 yum -y install expat-devel.x86_64 yum -y install libcurl-devel.x86_64 yum -y install xerces-c-devel.x86_64 yum -y install unixODBC-devel.x86_64 yum -y install sqlite-devel.x86_64 yum -y install libspatialite-devel.x86_64 yum -y install libspatialite.x86_64 yum -y install openjpeg-devel.x86_64 yum -y install openjpeg-libs.x86_64 yum -y install pcre-devel.x86_64 yum -y install ocaml-csv-devel.x86_64 yum -y install geos-devel.x86_64 yum -y install pam-devel.x86_64 yum -y install uuid-devel.x86_64 yum -y install python-devel.x86_64 yum -y install perl-devel.x86_64 yum -y install tcl.x86_64 yum -y install tcl-devel.x86_64 yum -y install cmake yum -y install cmake28.x86_64 yum -y install CUnit-devel.x86_64 yum -y install libtiff-devel.x86_64 yum -y install libjpeg-turbo-devel.x86_64 yum -y install hdf-devel.x86_64 yum -y install hdf5-devel.x86_64 yum -y install netcdf-devel.x86_64 yum -y install jasper-devel.x86_64 yum -y install nas-devel.x86_64 yum -y install gsl-devel.x86_64 yum -y install libdap.x86_64 yum -y install proj.x86_64 yum -y install proj-devel.x86_64 yum -y install proj-epsg.x86_64 yum -y install proj-nad.x86_64 yum -y install proj-static.x86_64 yum -y install ogdi-devel.x86_64 yum -y install boost.x86_64 yum -y install boost-math.x86_64 yum -y install boost-devel.x86_64 yum -y install gmp-devel.x86_64 yum -y install mpfr-devel.x86_64 yum -y install qt-devel.x86_64 yum -y install qt3-devel.x86_64 yum -y install gtk+-devel.x86_64
コンパイルインストール
#PostgreSQL-9.3.4コンパイル・インストール #PostgreSQLはroot権限で実行できないため、以下のユーザーを追加する #make時はオプション「-j6」を指定して並列でコンパイルする。 #重要:PostgreSQLのバックエンドやファンクションの多くがC++言語で書かれているため、 # 安定運用のためにはstdc++ラブラリーをリンクして原因不明のトラブルを回避する。 wget http://ftp.postgresql.org/pub/source/v9.3.4/postgresql-9.3.4.tar.gz tar zxvf postgresql-9.3.4.tar.gz cd postgresql-9.3.4 LDFLAGS=-lstdc++ ./configure --prefix=/usr --libdir='${prefix}/lib64' make -j8 world make install-world cd .. #libgeotiff コンパイルインストール wget http://download.osgeo.org/geotiff/libgeotiff/libgeotiff-1.4.0.tar.gz tar xvfz libgeotiff-1.4.0.tar.gz cd libgeotiff-1.4.0 ./configure --prefix=/usr --libdir='${prefix}/lib64' --with-zlib=/usr --with-jpeg=/usr --enable-incode-epsg make -j8 make install cd .. #計算幾何(Computational Geometry Algorithms Library)ライブラリー #CGALのコンパイル・インストール wget https://gforge.inria.fr/frs/download.php/33525/CGAL-4.4.tar.gz tar zxvf CGAL-4.4.tar.gz cd CGAL-4.4 #★★以下修正注意★★ #ヘッダー修正ファイル:include/CGAL/Mpzf.h #57行目に以下の定義を追加して保存する。 vi include/CGAL/Mpzf.h #ifndef mpn_sqr #define mpn_sqr(dest,a,n) mpn_mul_n(dest,a,a,n) #endif #インストールライブラリーのディレクトリを変更してからcmakeを実行する #ライブラリーのインストール先の「/usr/lib」から「/usr/lib64」に変更する。 #cmake28バージョンを使う場合もあるため注意する。 sed -i -e "s|CGAL_INSTALL_LIB_DIR \"lib\"|CGAL_INSTALL_LIB_DIR \"lib64\"|g" CMakeLists.txt cmake -DBOOST_ROOT=/usr \ -DCMAKE_BUILD_TYPE=Release -DBOOST_LIBRARYDIR=/usr/lib64 \ -DWITH_GMP=y -DGMP_INCLUDE_DIR=/usr/include -DGMP_LIBRARIES_DIR=/usr/lib64 \ -DMPFR_INCLUDE_DIR=/usr/include -DMPFR_LIBRARIES_DIR=/usr/lib64 \ -DCMAKE_INSTALL_PREFIX=/usr . make -j8 make install cd .. #遺伝的アルゴリズム(genetic algorithm) #GAUL コンパイル・インストール wget http://sourceforge.net/projects/gaul/files/gaul-devel/0.1850-0/gaul-devel-0.1850-0.tar.gz tar zxvf gaul-devel-0.1850-0.tar.gz cd gaul-devel-0.1850-0 ./configure --prefix=/usr --libdir='${prefix}/lib64' --enable-slang=no make -j8 make install cd .. #GoogleのKMLサーポートライブラリーコンパイル・インストール #--disable-swigに設定して他言語のライブラリーを無効にする。必要な場合は、JDKなどを先にインストールする。 svn checkout http://libkml.googlecode.com/svn/trunk/ libkml-1.3.0 cd libkml-1.3.0 ./autogen.sh ./configure --prefix=/usr --libdir='${prefix}/lib64' --disable-swig make -j8 make install cd .. #GDAL(Geospatial Data Abstraction Library) のコンパイル・インストール wget http://download.osgeo.org/gdal/1.10.1/gdal-1.10.1.tar.gz tar zxvf gdal-1.10.1.tar.gz cd gdal-1.10.1 ./configure --prefix=/usr --libdir='${prefix}/lib64' make -j8 make install cd .. #CGALラッパー(SFCGAL)インストール(PostGIS) #バックグラウンドで3Dデータをハンドリングする際に使われるが、必要ソフトが #CentOS-6.5にはインストールされているGCCやBOOSTバージョンとは合わないため、 #コンパイルができない。自力でGCCとBOOSTをコンパイル・インストールする場合、 #以下の方法でコンパイルし、ライブラリーをPostGISに組み込む。 #wget https://github.com/Oslandia/SFCGAL/archive/v1.0.4.tar.gz #mv v1.0.4.tar.gz SFCGAL-1.0.4.tar.gz #tar xvf SFCGAL-v1.0.4.tar.gz #cmake28 -DCMAKE_INSTALL_PREFIX=/usr . # #cmake28 -DBOOST_ROOT=/usr \ # -DCMAKE_BUILD_TYPE=Release -DBOOST_LIBRARYDIR=/usr/lib64 \ # -DWITH_GMP=y -DGMP_INCLUDE_DIR=/usr/include -DGMP_LIBRARIES_DIR=/usr/lib64 \ # -DMPFR_INCLUDE_DIR=/usr/include -DMPFR_LIBRARIES_DIR=/usr/lib64 \ # -DCMAKE_INSTALL_PREFIX=/usr . #PostGIS2コンパイルインストール wget http://download.osgeo.org/postgis/source/postgis-2.1.2.tar.gz tar zxvf postgis-2.1.2.tar.gz cd postgis-2.1.2 ./configure --prefix=/usr --libdir='${prefix}/lib64' make -j8 make install cd ../ #pgRoutin-2.0.0コンパイルインストール wget https://github.com/pgRouting/pgrouting/archive/v2.0.0.tar.gz mv v2.0.0.tar.gz pgrouting-2.0.0.tar.gz tar zxvf pgrouting-2.0.0.tar.gz cd pgrouting-2.0.0 mkdir build cd build cmake28 -DWITH_DD=ON -DBoost_NO_BOOST_CMAKE=ON .. make -j8 make install cd ../../
DB設定
#postgresユーザがなければ追加する useradd postgres mkdir -p /var/pgsql/data chown -R postgres:postgres /var/pgsql/ #DBの初期化 #--encoding:DBのデフォルト文字エンコーディング設定オプション。UTF-8指定 #--no-locale:--no-localeは--locale=Cと同じ意味。Cロケール以外の設定では性能に影響が出る場合がある。 su postgres -c'/usr/bin/initdb --encoding=UTF-8 --no-locale -D /var/pgsql/data' #サービスに追加し、サービスとして運用する。 cp postgresql-9.3.4/contrib/start-scripts/linux /etc/init.d/postgres #ファイルを開きディレクトリに合わせて修正 vi /etc/init.d/postgres prefix=/usr PGDATA="/var/pgsql/data" #実行権限設定 chmod 700 /etc/init.d/postgres #サービスに登録 chkconfig postgres on #DB起動 #/etc/init.d/postgres start #サービス起動 service postgres start
GIS テンプレート作成
#PostGISテンプレートDB作成(PostgreSQL-9.3.4での「postgis/pgrouting」サポート) su postgres createdb -U postgres -T template0 -E UTF-8 template_gis psql -d template_gis -c "CREATE EXTENSION postgis;" psql -d template_gis -c "CREATE EXTENSION postgis_topology;" psql -d template_gis -c "CREATE EXTENSION fuzzystrmatch;" psql -d template_gis -c "CREATE EXTENSION postgis_tiger_geocoder;" psql -d template_gis -c "CREATE EXTENSION pgrouting;" #GISサーポートデータベース作成 createdb -U postgres -T template_gis -E UTF-8 testgis
pgbench(DBベンチマーク)
#以下のオプションで初期化し一般性能を確認する。 #チューニングを行わない状態で確認後、調整しする。 #スケーリングファクター[-s]単位:10万件 #100万件のデータ[-s 10]検証 #10万件当たり15MBディスク容量 pgbench -i -s 10 testgis #条件を指定してベンチマーク #検索処理のみ実行する #同時に接続するクライアント数は10 #1クライアントあたりのトランザクション数は100 #読み込みのみのオプションでテスト pgbench -S -c 10 -t 100 testgis #結果サンプル starting vacuum...end. transaction type: SELECT only scaling factor: 10 query mode: simple number of clients: 10 number of threads: 1 number of transactions per client: 100 number of transactions actually processed: 1000/1000 tps = 13445.739717 (including connections establishing) tps = 19127.041812 (excluding connections establishing)
PostgreSQLの自動チューニング設定スクリプト
#注意:以下のスクリプトは、上記の方法でインストールした場合のみです。 #他で使用する場合は適宜変更してご使用ください。 #読み込みが圧倒的に多い場合は、「web」オプションを選択すると性能が向上します。 sh pgsql_autoconf.sh web vi pgsql_autoconf.sh #!/bin/sh # pgsql_autoconf.sh: # # This script automatically detects system RAM and other resources # and modifies $PG_DATA_DIR/postgresql.conf to configure the server # for one of three uses: web, oltp, or data warehousing. # # Author: rocket357@users.sourceforge.net # License: BSD # # このスクリプトは以下のスライド発表の際に使われたようです: # http://www.slideshare.net/oscon2007/performance-whack-a-mole # # 以下の内容は上のURLを参考に作成されました。 # "What Color Is My Application" の部分です。 # # web = web application backend # 1) DB smaller than RAM # 2) 90% or more simple read queries # oltp = online transaction processing # 1) db slightly larger than RAM, up to 1 TB # 2) 20-40% small data write queries # 3) some long transactions # dw = data warehousing # 1) large to huge databases (100 GB to 100 TB) # 2) large complex report queries # 3) large bulk loads of data # 4) also called "Decision Support" or "Business Intelligence" # CHANGELOG # v0.1 - Initial post to LQ.org set -e # bomb out if something goes wrong... if [ ! `whoami` = 'root' ]; then echo "This script needs to run as root because" echo "it alters shm{max,mni,all}" exit fi if [ -z "$1" ]; then echo "Usage: ./pgsql_autoconf.sh [template]" echo "Where [template] is one of:" echo " 'web' (web backend server)" echo " 'oltp' (online transaction processing)" echo " 'dw' (data warehouse)" echo "See http://www.slideshare.net/oscon2007/performance-whack-a-mole" echo "for further explanation." exit fi echo -n "Will this machine be dedicated (i.e. PostgreSQL is the only active service)? (y/n) " read dedicated ################################### ### USER CONFIGURABLE VARIABLES ### ################################### # 構築環境によって下の設定内容は異なりますので、適宜変更してください。 PGHOMEDIR=/var/pgsql PGDATADIR=$PGHOMEDIR/data CONFIG_FILE=/var/pgsql/data/postgresql.conf TEMP_FILE=${CONFIG_FILE}.TMP # performance-whack-a-mole (上記リンク参照) SHARED_BUFFER_RATIO=0.25 EFFECTIVE_CACHE_RATIO=0.67 if [ "$1" = "web" ]; then # web backend server NUM_CONN=400 WORK_MEM=512 # kB CHECKPOINT_SEG=8 MAINT_WORK_MEM=128MB elif [ "$1" = "oltp" ]; then # online transaction processing if [ $dedicated = 'y' ]; then NUM_CONN=50 WORK_MEM=8192 # kB else NUM_CONN=200 WORK_MEM=2048 # kB fi CHECKPOINT_SEG=16 MAINT_WORK_MEM=128MB elif [ "$1" = "dw" ]; then # data warehousing NUM_CONN=100 WORK_MEM=131072 # kB CHECKPOINT_SEG=64 MAINT_WORK_MEM=1024MB fi ####################################### ### END USER CONFIGURABLE VARIABLES ### ####################################### # first let's locate the configuration file... if [ -e $CONFIG_FILE ]; then echo "Backing up original config file to $CONFIG_FILE.BACKUP" cp $CONFIG_FILE $CONFIG_FILE.BACKUP echo "Backing up /etc/sysctl.conf to $PGHOMEDIR/sysctl.conf.BACKUP" cp /etc/sysctl.conf $PGHOMEDIR/sysctl.conf.BACKUP fi OS_TYPE=`uname -s` ### LINUX if [ "$OS_TYPE" = "Linux" -o "$OS_TYPE" = "GNU/Linux" ]; then SYSCTL_KERNEL_NAME="kernel" MAX_MEM=`grep MemTotal /proc/meminfo | sed -e 's/^[^0-9]*//' | cut -d' ' -f1` OS_PAGE_SIZE=`getconf PAGE_SIZE` ### OPENBSD elif [ "$OS_TYPE" = "OpenBSD" ]; then SYSCTL_KERNEL_NAME="kern.shminfo" MAX_MEM=$(echo "scale=0; `dmesg | grep \"real mem\" | cut -d\"=\" -f2 | cut -d\"(\" -f1`/1024" | bc -l ) # convert to kB OS_PAGE_SIZE=`sysctl hw.pagesize | cut -d'=' -f2` ### UNKNOWN else echo "$OS_TYPE isn't supported! Please send an e-mail to rocket357@users.sourceforge.net to have this OS added!" exit fi echo "Done!" # make sure work_mem isn't greater than total memory divided by number of connections... WORK_MEM_KB=$(echo "scale=0; $MAX_MEM/$NUM_CONN" | bc -l) if [ $WORK_MEM_KB -gt $WORK_MEM ]; then while [ $WORK_MEM -lt $WORK_MEM_KB ]; do WORK_MEM_TEMP=$(echo "scale=0; $WORK_MEM*2" | bc -l) if [ $WORK_MEM_TEMP -lt $WORK_MEM_KB ]; then WORK_MEM=$(echo "scale=0; $WORK_MEM*2" | bc -l) else WORK_MEM_KB=0 fi done WORK_MEM_KB=$WORK_MEM; fi WORK_MEM=$(echo "scale=0; $WORK_MEM_KB/1024" | bc -l)MB # OS settings HOSTNAME=`hostname` # shm{mni,all,max} are critical to PostgreSQL starting. # They must be high enough for these settings: # max_connections # max_prepared_transactions # shared_buffers # wal_buffers # max_fsm_relations # max_fsm_pages echo -n "Checking the current kernel's shared memory settings..." # SHMMAX # # (BLOCK_SIZE + 208) * ((MAX_MEM * 1024) / PAGE_SIZE) * $SHARED_BUFFER_RATIO) SHMMAX=`sysctl $SYSCTL_KERNEL_NAME.shmmax | cut -d'=' -f2` OPTIMAL_SHMMAX=`echo "scale=0; (8192 + 208) * (($MAX_MEM * 1024) / $OS_PAGE_SIZE) * $SHARED_BUFFER_RATIO" | bc -l | cut -d'.' -f1`0 if [ $SHMMAX -lt $OPTIMAL_SHMMAX ]; then sysctl $SYSCTL_KERNEL_NAME.shmmax=$OPTIMAL_SHMMAX echo "$SYSCTL_KERNEL_NAME.shmmax=$OPTIMAL_SHMMAX" >> /etc/sysctl.conf fi # SHMMNI # # 4096 - 8192 SHMMNI=`sysctl $SYSCTL_KERNEL_NAME.shmmni | cut -d'=' -f2` OPTIMAL_SHMMNI=32768 # systems with large amounts of RAM, drop if you don't have 128GB or so... if [ $SHMMNI -lt $OPTIMAL_SHMMNI ]; then sysctl $SYSCTL_KERNEL_NAME.shmmni=$OPTIMAL_SHMMNI echo "$SYSCTL_KERNEL_NAME.shmmni=$OPTIMAL_SHMMNI" >> /etc/sysctl.conf fi # SHMALL # # SHMMAX / PAGE_SIZE SHMALL=`sysctl $SYSCTL_KERNEL_NAME.shmall | cut -d'=' -f2` OPTIMAL_SHMALL=`echo "scale=0; $OPTIMAL_SHMMAX / $OS_PAGE_SIZE" | bc -l | cut -d'.' -f1` if [ $SHMALL -lt $OPTIMAL_SHMALL ]; then sysctl $SYSCTL_KERNEL_NAME.shmall=$OPTIMAL_SHMALL echo "$SYSCTL_KERNEL_NAME.shmall=$OPTIMAL_SHMALL" >> /etc/sysctl.conf fi # convert MAX_MEM to MB MAX_MEM=$(echo "scale=0; $MAX_MEM/1024" | bc -l) SHARED_BUFFERS=$(echo "scale=0; $MAX_MEM * $SHARED_BUFFER_RATIO" | bc -l | cut -d'.' -f1) # There has been debate on this value on the postgresql mailing lists. # You might not get any performance gain over 8 GB. Please test! if [ $SHARED_BUFFERS -gt 12000 ]; then SHARED_BUFFERS=12000MB; else SHARED_BUFFERS="$SHARED_BUFFERS"MB fi if [ "$OS_TYPE" = "Linux" -o "$OS_TYPE" = "GNU/Linux" ]; then echo "Setting virtual memory sysctls" sysctl vm.swappiness=0 echo "vm.swappiness=0" >>/etc/sysctl.conf sysctl vm.overcommit_memory=2 echo "vm.overcommit_memory=2" >>/etc/sysctl.conf # >8GB RAM? Don't let dirty data build up...this can cause latency issues! # These settings taken from "PostgreSQL 9.0 High Performance" by Gregory Smith if [ $MAX_MEM -gt 8192 ]; then echo 2 > /proc/sys/vm/dirty_ratio echo 1 > /proc/sys/vm/dirty_background_ratio else echo 10 > /proc/sys/vm/dirty_ratio echo 5 > /proc/sys/vm/dirty_background_ratio fi fi WAL_BUFFERS="16MB" EFFECTIVE_CACHE_SIZE=$(echo "scale=0; $MAX_MEM * $EFFECTIVE_CACHE_RATIO" | bc -l | cut -d'.' -f1)MB ### NOW THE FUN STUFF!! echo "Applying system configuration settings to the server..." echo "This system appears to have $MAX_MEM MB maximum memory..." if [ -e $CONFIG_FILE ]; then echo "Setting data_directory to: $PGDATADIR" echo "Setting listen_addresses to: '*'" echo "Setting port to: 5432" echo "Setting max_connections to: $NUM_CONN" echo "Setting shared_buffers to: $SHARED_BUFFERS" echo "Setting work_mem to: $WORK_MEM" echo "Setting effective_cache_size to: $EFFECTIVE_CACHE_SIZE" echo "Setting checkpoint_segments to: $CHECKPOINT_SEG" echo "Setting maintenance_work_mem to: $MAINT_WORK_MEM" echo "Setting wal_buffers to: $WAL_BUFFERS" sed \ -e "s@[#]*data_directory = .*@data_directory = \'$PGDATADIR\'@" \ -e "s/[#]*listen_addresses = .*/listen_addresses = \'\*\'/" \ -e "s/[#]*port = .*/port = 5432/" \ -e "s/[#]*max_connections = .*/max_connections = $NUM_CONN/" \ -e "s/[#]*ssl = .*/ssl = false/" \ -e "s/[#]*shared_buffers = .*/shared_buffers = $SHARED_BUFFERS/" \ -e "s/[#]*work_mem = .*/work_mem = $WORK_MEM/" \ -e "s/[#]*effective_cache_size = .*/effective_cache_size = $EFFECTIVE_CACHE_SIZE/" \ -e "s/[#]*checkpoint_segments = .*/checkpoint_segments = $CHECKPOINT_SEG/" \ -e "s/[#]*maintenance_work_mem = .*/maintenance_work_mem = $MAINT_WORK_MEM/" \ -e "s/[#]*wal_buffers = .*/wal_buffers = $WAL_BUFFERS/" \ -e "s/[#]*cpu_tuple_cost = .*/cpu_tuple_cost = 0.002/" \ -e "s/[#]*cpu_index_tuple_cost = .*/cpu_index_tuple_cost = 0.0002/" \ -e "s/[#]*cpu_operator_cost = .*/cpu_operator_cost = 0.0005/" \ $CONFIG_FILE > $TEMP_FILE mv $TEMP_FILE $CONFIG_FILE else echo "Unable to locate the PostgreSQL config file! Can't continue!" exit 1 fi echo "Done!"
確認と設定反映
sysctl -p service postgres restart