2016.06.13
CentOS 7 に Greenplum DB クラスタを構築してみた
こんにちは。次世代システム研究室のデータベース・Hadoop (Hive, HBase) まわり担当のM.K.です。
最近 Hadoop 関連の技術動向を見ることが多かったのですが、今回は MPP (Massively Parallel Processing:大規模並列処理)の仕組みを RDB に採用し、2015年にオープンソースになった Greenplum Databaseを触ってみようと思います。
Greenplum DB は PostgreSQL をベースにしたもので、PostgreSQL に MPP と言えば Amazon Redshift が一番有名ではないでしょうか。Redshift と同様、RDB の基礎となるトランザクション機能の上に大規模並列処理を拡張しているところが Hadoop 系 MPP (Impalaなど) とは異なるポイントです。
動作環境
先ず Greenplum DB をインストールするサーバーの動作環境を、Pivotal ドキュメントのシステム要件で確認します。
今回は GMO アプリクラウドの検証環境を利用して、確認した要件を満たすスペックの仮想サーバーを利用しました。
[table id=13 /]
スタンドアローンで Greenplum DB を構築してもあまり意味がないので、最初から冗長化した構成を検討しています。
Greenplum DB は「マスター」と「セグメント」とよばれるホストで構成されます。
マスターホストは2台で冗長化構成が取ることができ、セグメントホストは Hadoop で言うところのデータノードのような位置づけでデータの格納や並列処理を行います。
今回の検証ではマスターホストを2台(冗長化)、セグメントホストを6台のサーバー構成としました。
CentOS 7 のセットアップ
Greenplum DB を構築するための OS セットアップを一つづつしていきます。
※以下の作業は特に指定がない場合 root ユーザーで作業
SELinux無効化
SELinux が無効化されているか確認(全ホスト)。SELinux が有効になっていた場合は無効化してください。
sestatus
SELinux status: disabled
ファイアーウォールの設定
CentOS 7 までは iptables の操作でしたが、CentOS 7 は firewalld の操作がメインになります。
今回のGMOアプリクラウドの検証環境ではファイアーウォール設定は無効化して問題ないので、
ファイアーウォールが無効化されているかどうか確認します。
/sbin/chkconfig --list iptables
ではなく、
systemctl is-enabled firewalld
disabled
systemctl status
firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled) Active: inactive (dead)
OS パラメータのセットアップ
Pivotal ドキュメントの推奨 OS パラメータ設定を見て設定します(全ホスト)。
今回は Pivotal ドキュメントの通りに設定しようと思いますので、/etc/sysctl.conf に以下の設定を追加します。
echo ' kernel.shmmax = 500000000 kernel.shmmni = 4096 kernel.shmall = 4000000000 kernel.sem = 250 512000 100 2048 kernel.sysrq = 1 kernel.core_uses_pid = 1 kernel.msgmnb = 65536 kernel.msgmax = 65536 kernel.msgmni = 2048 net.ipv4.tcp_syncookies = 1 net.ipv4.ip_forward = 0 net.ipv4.conf.default.accept_source_route = 0 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_max_syn_backlog = 4096 net.ipv4.conf.all.arp_filter = 1 net.ipv4.ip_local_port_range = 1025 65535 net.core.netdev_max_backlog = 10000 net.core.rmem_max = 2097152 net.core.wmem_max = 2097152 vm.overcommit_memory = 2 ' >> /etc/sysctl.conf sysctl -p
limits.conf 設定
OSユーザーのリソース制限に関して /etc/security/limits.conf に以下の設定を行います。
sed -i -e '/# End of file/d' /etc/security/limits.conf echo '* soft nofile 65536 * hard nofile 65536 * soft nproc 131072 * hard nproc 131072 # End of file' >> /etc/security/limits.conf
XFS のマウントオプションを本番仕様に変更
はじめにデータ領域のマウントポイントのデバイスファイルを確認します。
cat /etc/fstab
# サンプル /dev/mapper/XXXXX-LV00 / xfs defaults 1 1 UUID=XXXXXXXXXXXXXXXXX /boot xfs defaults 1 2 /dev/mapper/XXXXX-LV02 /var xfs defaults 1 2 /dev/mapper/XXXXX-LV01 swap swap defaults 0 0
今回の検証環境では /var がデータ領域としてたくさんのディスク容量が割り当てられているので、/var 配下を Greenplum DB 用とします。
Greenplum DB のデータ領域は xfs ファイルシステムが推奨されており、CentOS 7 はデフォルトのファイルシステムが xfs のため都合が良いですが、xfs オプションを推奨されている内容に変更します。
/var を強制アンマウントします。
umount -l /dev/mapper/XXXXX-LV02
推奨の xfs オプションでマウントし直します。
mount -t xfs -O rw,suid,exec,auto,nouser,async,nodev,noatime,inode64,allocsize=16m /dev/mapper/XXXXX-LV02 /var
再起動しても上記のようにマウントするように /etc/fstab を修正します。
sed -i -e 's/^\/dev\/mapper\/XXXXX\-LV02 .*/\/dev\/mapper\/XXXXX-LV02 \/var xfs rw,suid,exec,auto,nouser,async,nodev,noatime,inode64,allocsize=16m 1 2/g' /etc/fstab
/etc/fstab を確認します。
cat /etc/fstab
# サンプル /dev/mapper/XXXXX-LV00 / xfs defaults 1 1 UUID=XXXXXXXXXXXXXXXXX /boot xfs defaults 1 2 /dev/mapper/XXXXX-LV02 /var xfs rw,suid,exec,auto,nouser,async,nodev,noatime,inode64,allocsize=16m 1 2 /dev/mapper/XXXXX-LV01 swap swap defaults 0 0
Linux disk I/O スケジューラーの設定
Greenplum DB では、Linux disk I/O スケジューラーを deadline にするのが推奨されていますが、今回の環境では none に固定されていたため、この設定はスキップします。
HDD か SSD かで変わってきますので環境によって適した値にします。
#サンプル cat /sys/block/dm-2/queue/scheduler
none
ディスクデバイスの read-ahead 値の設定
Greenplum DB では、ディスクデバイスの read-ahead 値を 8192 から 16384 に増やすことが推奨されています。
Linux disk I/Oスケジューラーを deadline にするのと同様、HDD 向けの設定と思われるので、SSD を利用している場合は別の値を検証してみてください。
blockdev コマンドで read-ahead 値を確認。
/sbin/blockdev --getra /dev/mapper/XXXXX-LV02
blockdev コマンドで read-ahead 値を変更。
/sbin/blockdev --setra 16384 /dev/mapper/XXXXX-LV02
blockdev コマンドでの変更は boot すると元にもどるため、注意が必要です。
ホスト名の設定
今回は DNS サーバーを使わないで /etc/hosts を使いますので、/etc/hosts を以下のように設定します。
# サンプル echo 'xxx.xxx.xxx.10 greenplum-m1 xxx.xxx.xxx.11 greenplum-m2 xxx.xxx.xxx.12 greenplum-s1 xxx.xxx.xxx.13 greenplum-s2 xxx.xxx.xxx.14 greenplum-s3 xxx.xxx.xxx.15 greenplum-s4 xxx.xxx.xxx.16 greenplum-s5 xxx.xxx.xxx.17 greenplum-s6 ' >> /etc/hosts
続いてホスト名を変更します。CentOS 7 からは hostnamectl コマンドだけで良くなりました。引数のホスト名はホストごとに変えてください。
hostnamectl set-hostname greenplum-m1
transparent_hugepageの無効化
Greenplum DB も transparent_hugepage の無効化が推奨されているので、実施します。
transparent_hugepage が有効かどうか確認
cat /sys/kernel/mm/transparent_hugepage/enabled
transparent_hugepage を無効化
echo never > /sys/kernel/mm/transparent_hugepage/enabled
ただし、再起動すると元通りになってしまうので、永続的な設定にする対応が必要です。
Pivotal ドキュメントでは、grubby コマンドでのやり方が書いてありますが、今回の環境ではうまくいかなかったため、CentOS7 の systemd を使った自作コマンドのサービス登録を行ってみることにしました。
transparent_hugepage を無効化する自作スクリプト(Mongo DB ドキュメント参照) を作成します。
echo '#!/bin/sh case $1 in start) if [ -d /sys/kernel/mm/transparent_hugepage ]; then thp_path=/sys/kernel/mm/transparent_hugepage elif [ -d /sys/kernel/mm/redhat_transparent_hugepage ]; then thp_path=/sys/kernel/mm/redhat_transparent_hugepage else exit 0 fi echo never > ${thp_path}/enabled echo never > ${thp_path}/defrag unset thp_path ;; esac' > /etc/init.d/disable-transparent-hugepages
blockdev コマンドの自作スクリプトも作成します。
echo '#!/bin/sh device_name=/dev/mapper/XXXXX-LV02 case $1 in start) if `mount | grep "^${device_name}" > /dev/null`;then /sbin/blockdev --setra 16384 ${device_name} else exit 0 fi unset device_name ;; esac' > /etc/init.d/blockdev-setra-LV02
今度は /etc/systemd/system/ の配下にそれぞれ Unit 定義ファイルを作ります。
echo '[Unit] Description=Disable Transparent Hugepages After=multi-user.target [Service] ExecStart=/etc/init.d/disable-transparent-hugepages start Type=simple [Install] WantedBy=multi-user.target' > /etc/systemd/system/disable-thp.service
echo '[Unit] Description=Blocdev --setra N After=multi-user.target [Service] ExecStart=/etc/init.d/blockdev-setra-logvol02 start Type=simple [Install] WantedBy=multi-user.target' > /etc/systemd/system/blockdev-setra-lv02.service
Unit 定義ファイルの補足
CentOS 7 からランレベルの定義が新しくなり、今までのランレベル 2~4 が multi-user.target という概念に変わります。
今回ランレベル 3 相当で最後に起動したかったので、WantedBy=multi-user.target、After=multi-user.target と定義しました。
Unit 定義ファイルについて気になる方はググってみてください。
作成したら忘れずに実行権限を付与しておきます。
chmod 755 /etc/init.d/disable-transparent-hugepages chmod 755 /etc/init.d/blockdev-setra-LV02 chmod 755 /etc/systemd/system/disable-thp.service chmod 755 /etc/systemd/system/blockdev-setra-lv02.service
CentOS 7 からは service コマンドではなく、systemctl コマンドを利用します。systemctl コマンドでサービスの有効化と起動を行います。
systemctl enable disable-thp systemctl start disable-thp systemctl enable blockdev-setra-lv02 systemctl start blockdev-setra-lv02
サーバー再起動と確認
上記の設定が一通り終わったら再起動して、再起動後も正しい設定値担っているか確認します。
reboot
上記の設定と再起動を全ホストで実施したら、CentOS 7 のセットアップまで完了です。
Greenplum DB をインストール
今回 Greenplum DB のインストールは GitHub に公開されているソースコードをビルドする方式で行いました。
GitHub ページにあるように、Greenplum DB本体の gpdb だけでなく、コストベースオプティマイザー(CBO) の gporca も一緒にビルドすることにしました。実際に運用するとき CBO を利用すると思われるためです。
gporca をインストールするには gpos と gp-xerces も必要になるので、結局、
をビルドしました。
鼻息荒くやってみたものの、configure や make や make install でひたすらエラーが出ては調べて足りないパッケージをインストールするという、ビルド地獄に陥ってしまいました・・・。
yum で追加したパッケージ
今回の環境で足りなかったパッケージは、最終的には以下のものです。予め yum などでインストールしておくことを強くオススメします。
yum -y install wget yum -y install git yum -y install gcc yum -y install gcc-c++ yum -y install bison yum -y install flex yum -y install libedit-devel yum -y install zlib zlib-devel yum -y install epel-release yum -y install --enablerepo=epel cmake3 yum -y install perl-devel perl-ExtUtils-Embed yum -y install python-devel yum -y install libevent libevent-devel yum -y install libxml2 libxml2-devel yum -y install libcurl libcurl-devel yum -y install bzip2 bzip2-devel yum -y install net-tools yum -y install libffi-devel yum -y install openssl-devel
gpos のインストール
最初に gpos をビルドします。
cd /usr/local/src git clone https://github.com/greenplum-db/gpos cd gpos mkdir build cd build cmake3 ../ make -j7 make install
gp-xerces のインストール
続けてに gp-xerces をビルドします。
cd /usr/local/src git clone https://github.com/greenplum-db/gp-xerces cd gp-xerces mkdir build cd build ../configure --prefix=/usr/local make -j7 make install
gporca のインストール
次にgporcaをインストールします。
cd /usr/local/src git clone https://github.com/greenplum-db/gporca.git cd gporca mkdir build cd build cmake3 ../ make -j7 make install
apr のインストール
gpdb のビルドでどうしても configure が通らなくてハマりましたが、apr をインストールすることで解決しました。
cd /usr/local/src wget http://www-eu.apache.org/dist//apr/apr-1.5.2.tar.gz tar zxvf apr-1.5.2.tar.gz cd apr-1.5.2 ./configure --prefix=/usr/local make -j7 make install
gpdb のインストール
ようやく最後の gpdb をインストールします。
cd /usr/local/src git clone https://github.com/greenplum-db/gpdb cd gpdb ./configure --enable-orca --with-perl --with-python --with-libxml --prefix=/usr/local/gpdb make -j7 make install
これで Greenplum DB (CBO付き) のインストールが完了です。
Greenplum DB のクラスタを構築
インストールでたくさんハマりましたが、クラスタ構築でもいっぱいハマりました・・・。
今度も足りないパッケージがまた幾らかあったのと、Python の特定のモジュールがまだ入ってなかったため、何度もエラーが発生。そこで最初に Python モジュールをインストールします。
Python モジュールのインストール
はじめに Python モジュールを簡単にインストールできる pip をインストール。
cd /usr/local/src curl -kL https://bootstrap.pypa.io/get-pip.py | python
今度は pip を使って、paramiko、psutil、lockfile モジュールをインストール。
pip install paramiko pip install psutil pip install lockfile
マスターホストからクラスタ構築
クラスタ構築に関するPivotalドキュメントを参考に実施していきます。
ここからはマスターホストから各ホストに root ユーザーでリモート接続することが前提になります。
今回の環境では greenplum-m1 をマスターホストとしました。
先ず、greenplum-m1 に hostfile_exkeys ファイルというものを用意します。配置場所は任意の場所で構いません。
greenplum-m1 で作業
echo 'greenplum-m1 greenplum-m2 greenplum-s1 greenplum-s2 greenplum-s3 greenplum-s4 greenplum-s5 greenplum-s6' > /usr/local/gpdb/hostfile_exkeys
hostfile_exkeys ファイルは今回はホスト名のみを記述していますが、ネットワークインターフェースが各ホストで二つあり、どちらも同時に利用するような場合などは、
greenplum-m1 greenplum-m1-1 greenplum-m1-2 greenplum-m2 greenplum-m2-1 greenplum-m2-2 greenplum-s1 greenplum-s1-1 greenplum-s1-2 ...
というように書きます。詳細は Pivotal ドキュメントを確認してください。
root ユーザーによるパスワードなしの ssh 接続
ここで、greenplum-m1 から全ホストに root ユーザーでパスワードなしの ssh 接続ができるようにしておきます。
greenplum-m1 の root ユーザーで ssh-keygen を使って秘密鍵と公開鍵を生成し、公開鍵を全ホストの root ユーザーの authorized_keys に追記します。このとき、greenplum-m1 の authorized_keys にも追記してください。
greenplum_path.sh の修正
Greenplum DB をインストールしたところに入っている、環境変数をセットするための greenplum_path.sh の内容が一部今回のインストールとあっていなかったので、greenplum_path.sh を修正しました(これを最初直さなかったために、構築の最後の方でエラーが出て困りました)。
vi /usr/local/gpdb/greenplum_path.sh
GPHOME=/usr/local/gpdb # Replace with symlink path if it is present and correct if [ -h ${GPHOME}/../greenplum-db ]; then GPHOME_BY_SYMLINK=`(cd ${GPHOME}/../greenplum-db/ && pwd -P)` if [ x"${GPHOME_BY_SYMLINK}" = x"${GPHOME}" ]; then GPHOME=`(cd ${GPHOME}/../greenplum-db/ && pwd -L)`/. fi unset GPHOME_BY_SYMLINK fi #setup PYTHONHOME #if [ -x $GPHOME/ext/python/bin/python ]; then # PYTHONHOME="$GPHOME/ext/python" #fi PYTHONPATH=$GPHOME/lib/python #PATH=$GPHOME/bin:$PYTHONHOME/bin:$PATH PATH=$GPHOME/bin:$PATH #LD_LIBRARY_PATH=$GPHOME/lib:$PYTHONHOME/lib:$LD_LIBRARY_PATH LD_LIBRARY_PATH=$GPHOME/lib:/usr/local/lib:/usr/lib OPENSSL_CONF=$GPHOME/etc/openssl.cnf export GPHOME export PATH export LD_LIBRARY_PATH export PYTHONPATH export PYTHONHOME export OPENSSL_CONF
修正箇所は、setup PYTHONHOME とその直後の IF 文のコメントアウト、環境変数 LD_LIBRARY_PATH および PATH の内容です。
特に LD_LIBRARY_PATH の中に gporca を入れていた /usr/local/lib が入ってなかったので付け加えました。
greenplum_path.sh を読み込んだら、gpseginstall を実施します。マスターホストで gpseginstall を行うと、必要なもの一式がセグメントホストに展開され、gpadmin ユーザーがこのタイミングで全ホストに作成されます。gpadmin ユーザーはパスワードなしでマスターホストから ssh 接続できるように準備されます。
source /usr/local/gpdb/greenplum_path.sh gpseginstall -f /usr/local/gpdb/hostfile_exkeys -u gpadmin -p passwordxxx
.bash_profile 修正
今後何かのたびに常に greenplum_path.sh を読み込むことになるので、このタイミングで予め全ホストの root ユーザーと gpadmin ユーザーの .bash_profile に追記しておきます。
全ホストで以下を実施 (root と gpadmin ユーザー)
予め一つ前の手順で修正した /usr/local/gpdb/greenplum_path.sh を全ホストに配布しておきます。
配布後に .bash_profile を書き換えます。
sed -i -e 's/^export PATH/source \/usr\/local\/gpdb\/greenplum_path.sh/g' .bash_profile echo 'export PATH' >> .bash_profile
Greenplum DB のデータディレクトリ作成
greenplum-m1で作業
# マスタホストのデータディレクトリ mkdir -p /var/gpdb/master chown gpadmin /var/gpdb/master
gpsshコマンドを使ってリモートで実施します。
# セカンダリのマスタホストのデータディレクトリ gpssh -h greenplum-m2 -e 'mkdir -p /var/gpdb/master' gpssh -h greenplum-m2 -e 'chown -R gpadmin /var/gpdb'
続いてセグメントホストも実施します。ファイルにセグメントホストを書き出して同時に処理します。
セグメントホストのデータディレクトリは、primaryとmirrorの二つ必要になります。
# 全セグメントホストのデータディレクトリ echo 'greenplum-s1 greenplum-s2 greenplum-s3 greenplum-s4 greenplum-s5 greenplum-s6' > /usr/local/gpdb/hostfile_gpssh_segonly gpssh -f /usr/local/gpdb/hostfile_gpssh_segonly -e 'mkdir -p /var/gpdb/segment/primary' gpssh -f /usr/local/gpdb/hostfile_gpssh_segonly -e 'mkdir -p /var/gpdb/segment/mirror' gpssh -f /usr/local/gpdb/hostfile_gpssh_segonly -e 'chown -R gpadmin /var/gpdb'
ntpサーバーのセットアップ
Greenplum DBのクラスタ構築を始める前にどのホストも時刻が同期されるようにntpサーバーセットアップをします(ntpサーバーのセットアップの詳細はここでは割愛)。
gpinitsystem_configの編集
クラスタ構築&初期化に関するPivotalドキュメントを参考にしていきます。
サンプルのgpinitsystem_configファイルをコピー、適切な値に編集します。
su - gpadmin $ mkdir -p ~/gpconfigs $ cp $GPHOME/docs/cli_help/gpconfigs/gpinitsystem_config ~/gpconfigs/gpinitsystem_config $ vi ~/gpconfigs/gpinitsystem_config
今回編集した箇所はgpinitsystem_configの中の4箇所です。
- declare -a DATA_DIRECTORY
- MASTER_HOSTNAME
- MASTER_DIRECTORY
- declare -a MIRROR_DATA_DIRECTORY
# FILE NAME: gpinitsystem_config # Configuration file needed by the gpinitsystem ################################################ #### REQUIRED PARAMETERS ################################################ #### Name of this Greenplum system enclosed in quotes. ARRAY_NAME="EMC Greenplum DW" #### Naming convention for utility-generated data directories. SEG_PREFIX=gpseg #### Base number by which primary segment port numbers #### are calculated. PORT_BASE=40000 #### File system location(s) where primary segment data directories #### will be created. The number of locations in the list dictate #### the number of primary segments that will get created per #### physical host (if multiple addresses for a host are listed in #### the hostfile, the number of segments will be spread evenly across #### the specified interface addresses). declare -a DATA_DIRECTORY=(/var/gpdb/segment/primary /var/gpdb/segment/primary /var/gpdb/segment/primary /var/gpdb/segment/primary /var/gpdb/segment/primary) #### OS-configured hostname or IP address of the master host. MASTER_HOSTNAME=greenplum-m1 #### File system location where the master data directory #### will be created. MASTER_DIRECTORY=/var/gpdb/master #### Port number for the master instance. MASTER_PORT=5432 #### Shell utility used to connect to remote hosts. TRUSTED_SHELL=ssh #### Maximum log file segments between automatic WAL checkpoints. CHECK_POINT_SEGMENTS=8 #### Default server-side character set encoding. ENCODING=UNICODE ################################################ #### OPTIONAL MIRROR PARAMETERS ################################################ #### Base number by which mirror segment port numbers #### are calculated. MIRROR_PORT_BASE=50000 #### Base number by which primary file replication port #### numbers are calculated. REPLICATION_PORT_BASE=41000 #### Base number by which mirror file replication port #### numbers are calculated. MIRROR_REPLICATION_PORT_BASE=51000 #### File system location(s) where mirror segment data directories #### will be created. The number of mirror locations must equal the #### number of primary locations as specified in the #### DATA_DIRECTORY parameter. declare -a MIRROR_DATA_DIRECTORY=(/var/gpdb/segment/mirror /var/gpdb/segment/mirror /var/gpdb/segment/mirror /var/gpdb/segment/mirror /var/gpdb/segment/mirror) ################################################ #### OTHER OPTIONAL PARAMETERS ################################################ #### Create a database of this name after initialization. #DATABASE_NAME=name_of_database #### Specify the location of the host address file here instead of #### with the the -h option of gpinitsystem. #MACHINE_LIST_FILE=/home/gpadmin/gpconfigs/hostfile_gpinitsystem
DATA_DIRECTORY、MIRROR_DATA_DIRECTORYにはカッコ付きのデータディレクトリの配列を書きます。同じディレクトリのパスを並べているのは、セグメントホストですべて同じデータディレクトのパスだからになります。
ここでハマったのですが、今回の環境は6台のセグメントホストなので6個のデータディレクトリを書いたら、エラーで構築できませんでした。
よくPivotalドキュメントを読んだら、この値の個数+1が全セグメントホスト数にならないといけなかったので、5個指定にしました。
gpinitsystem コマンド実施
gpinitsystemというクラスタ構築&初期化コマンドを実行します。
最初から冗長化オプションの-sと-Sを指定して作ります。ロケールの指定する-nオプションも付け加えました。
セグメントホストがリストアップされたファイルを用意して実行します。
$ cp -p /usr/local/gpdb/hostfile_gpssh_segonly ~/gpconfigs/hostfile_gpinitsystem $ gpinitsystem -c ~/gpconfigs/gpinitsystem_config -h ~/gpconfigs/hostfile_gpinitsystem -n ja_JP.utf8 -s greenplum-m1 -S
以下のように聞かれたら、yを入力します。
=> Continue with Greenplum creation? Yy/Nn
以下のように表示されたら、Greenplum DBのクラスタ構築が完了です。
=> Greenplum Database instance successfully created.
まとめ
ソースコードからビルドしてGreenplum DBクラスタを構築するのは、環境要因もありますが、足りないパッケージやPythonモジュールがたくさん出てきて思ったより大変でした。
それでも一回やってしまえば次からはだいぶ敷居が下がって作りやすくなるのではないでしょうか。Pivotalドキュメントはそれなりに充実しているので困ったときにすぐに調べられます。
今回はクラスタ構築まででしたが、次回はデータをロードしてクエリの検証をしてみたいと思います。
最後に
次世代システム研究室では、アプリケーション開発や設計を行うアーキテクトを募集しています。アプリケーション開発者の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ 募集職種一覧 からご応募をお願いします。
皆さんのご応募をお待ちしています。
グループ研究開発本部の最新情報をTwitterで配信中です。ぜひフォローください。
Follow @GMO_RD