Suppress the message “Supplied authorities: …” org.apache.hive.jdbc.Utils#parseURL emits

この記事は【2016年10月1日】と作成から2年以上経っているため、記事の内容が古い可能性があります。最新の情報を合わせてご確認されることを推奨いたします。

HiveServer2にJDBC経由で接続する際に、ログの設定によっては"Supplied authorities: ..."のようなメッセージが出力されます。hive-jdbcの依存するライブラリはcommons-logging、Log4J、SLF4Jなど様々なログライブラリを含んでおり非常にややこしいですが、今回はlogback+SLF4Jで統一するとしてタイトルのようなメッセージを抑制するために以下のようにまとめてみました。

pom.xml

HiveServer2へJDBC経由で接続するのに必要なライブラリは以下を参考にします。

https://cwiki.apache.org/confluence/display/Hive/HiveServer2+Clients

上記リンクを参考に以下のように設定してみました。dbutilsは今回のログの件とは関係なくおまけです。

logback.xml

続いてログの設定です。

実行してみる

最後に実行してみます。

結果は以下のようになりました。

warn

ちなみに以下のように設定すると、

“Supplied …”の部分は表示されます。

info

org.apache.hiveのロガーレベルだけwarn以上にするといい感じに抑制できます。

参考リンク

プログラミング Hive

プログラミング Hive

posted with amazlet at 16.09.30
Edward Capriolo Dean Wampler Jason Rutherglen
オライリージャパン
売り上げランキング: 102,695

レンタルサーバーお引越し

この記事は【2016年9月24日】と作成から2年以上経っているため、記事の内容が古い可能性があります。最新の情報を合わせてご確認されることを推奨いたします。

WordPressで運用しているあるサイトを、さくらレンタルサーバー(スタンダードプラン)からXSERVER(X10プラン)へ引越しすることにしました。

さくら(スタンダードプラン)とXSERVER(X10プラン)

さくらレンタルサーバーは、昔からお世話になっていて、大変使いやすく馴染みもあり且つコストパフォーマンスも高くてオススメなのですが、

  • たまには別のレンタルサーバーを使ってみたかった
  • WordPressを動かすにはもう少し高いパフォーマンスの出る環境がいい

という理由で別のレンタルサーバーへ引越しすることにしました(もちろんグレードの高いプランにする選択肢もありますが。。)。

色々ある中でもXSERVERさんにした理由は、

  • プライベート以外で使ったことがあり使い勝手をある程度知っていた事
  • サーバー環境がハイスペックである(らしい)事
  • サーバーパネルが充実している事
  • FastCGIやキャッシュモジュールによる高速化が期待できる事(WordPressの運用においては、プラグインやサーバー設定を組み合わせて高速化を図るケースが多いですが、Lowレベルでの仕組みが備わっているのは大変ありがたい)

といったところになります。

主要な機能の比較

以下にざっくりとコスト、機能の比較をまとめてみました。
※更新されている可能性もあるため、詳細は公式のサイトを参照してください。2016/9/22時点での内容になります

比較項目 さくらスタンダード XSERVER X10
料金
(1年契約で計算)
月額429円 月額1,000円
SSH接続
PHP動作モード cgi FastCGI
PHP Version
2016/9/22時点
4系、5系 5系、7系
独自ドメイン
WordPress
クイックインストール
データベース MySQL(20個)/ ver 5.5
SQLite
MySQL(50個)/ ver 5.7
ディスクスペース 100G 200G
マルチドメイン 最大20個 無制限
サブドメイン 無制限
SSL 共有SSL
ただし、SNI ネームベースの独自SSL対応
独自SSL
メールアカウント 制限なし 無制限
メーリングリスト ◯ (最大10) ◯ (最大20)
OS FreeBSD Linux
公式URL(※) さくらスタンダード wpXレンタルサーバー

(2016/9/22調べ)

PHP 7系、MySQL 5.7.xと最新に近いバージョンが使え、FastCGIというCGIよりも高速に動作するミドルウェアが使われているのもXSERVERの特徴です

パフォーマンスの違いは?

最新のWordPress(4.6.1)をインストールして、特別な設定なしでベンチマーク(Apache Bench)を実施してみた結果は以下のようになりました。時間帯やマルチテナント状況にも依存するかもしれませんがご参考までに(あまりに高い負荷をかけると迷惑がかかるので注意が必要です)。

Apache Bench

さくら スタンダード XServer X10

当然、比較するとコストが高いだけあってXserverの方が秒間に多くのリクエストをさばけています。このシンプルなベンチの結果では、さくらスタンダードより秒間5倍ものリクエストをさばくことができています。

GTMetrixによる比較

さくら スタンダードプラン XServer X10
bench-sakura-mask bench-xserver-mask

参考リンク

  • https://gtmetrix.com
  • https://help.sakura.ad.jp/hc/ja/articles/206053142–さくらのレンタルサーバ-基本仕様
  • https://www.xserver.ne.jp/functions/

 

XSERVERはこちら

無料お試し期間もあるので是非一度トライして見てください♫


   

スポンサーリンク

Sqoop import failed because of error “Make sure HIVE_CONF_DIR is set correctly”

この記事は【2016年8月6日】と作成から2年以上経っているため、記事の内容が古い可能性があります。最新の情報を合わせてご確認されることを推奨いたします。

Sqoop Import failed after CDH upgrading

Hadoop環境をCDH5.3.xから5.7.xへアップグレードするとsqoopは1.4.5から1.4.6になったが、sqoop importを実行しようとしたところ以下のようなエラーでhive-importに失敗してしまう。MapreduceジョブによるHDFS上の一時ディレクトリへの書き込みまでは問題なく進んでおり、最後のHiveCLIを起動してのLOAD DATAするところでエラーになっているようだった。

どうも参照しているHive関連のクラスが見つからないようだ。ソースを追っていくとHiveのLOAD DATAを実行しているのは以下の部分にあたる。

getHiveArgsをさらに追っていくと、Exceptionで落ちているところは以下。

HiveConfのクラスが見つからないということで、HIVEに関するクラスパスなどの環境変数を定義しているところを探してみる。

sqoopコマンドを追っていくと以下の箇所で環境変数であるHIVE_HOMEに関する設定を行なっていることがわかる。

私の環境では、/usr/lib/hive/の下に共通で使うライブラリを置いていたので、上記の処理の中でHIVE_HOME/usr/lib/hiveに向いてしまっていたようだった。しかし、私の環境ではCDHをClouderaManagerのParcelでインストールしているため、ここにhive本体は存在していない。

したがって、以下のように改めてHIVE_HOMEの正しいパスを指定してあげると、無事sqoopコマンドを実行することができた。

もしくは、/usr/lib/hiveをrmまたはmvすれば良いだろう。

参考リンク

  • http://www.ericlin.me/sqoop-hive-import-failed-after-upgrading-to-cdh5-4-x-or-cdh5-5-x
  • https://community.cloudera.com/t5/Batch-SQL-Apache-Hive/Error-with-quot-Make-sure-HIVE-CONF-DIR-is-set-correctly-quot/td-p/37423
  • https://github.com/apache/sqoop/commit/d408252086d4351eac211cfc2203dc15c660ad31

Parse error can be caused due to NUL character included in records with Sqoop

この記事は【2016年7月18日】と作成から2年以上経っているため、記事の内容が古い可能性があります。最新の情報を合わせてご確認されることを推奨いたします。

Sqoopを使ってRDBMとHadoop間でデータ転送を行なっている。Sqoopは、MapReduceジョブを実行し複数のMapタスクで並列にインポートやエクスポートを行なう。また、Sqoopはコマンドラインからsqoopコマンドを実行するだけで、データ転送に必要なテーブルのメタ情報の取得やRDBMとHadoop間でデータのやり取りをするインターフェースプログラムの生成やコンパイル、各Mapタスクへのデータスプリット計算などを内部で行ってくれるので、実行も非常に容易である。コマンドラインオプションも豊富に用意されており、多くの場合はそれらの組み合わせで十分対応できる。

Parse Error with Export

で、今回通常どおりSqoopを使ってデータ転送処理を実行していたところ、Sqoop Exportの実行時に以下のようなエラーになってしまった(以下のエラーはローカルで再現させたもの)。成功したMapタスクのデータは転送に成功しているが、失敗したMapタスクのデータは完全に転送されないためデータが不完全な状態になってしまう。parseに失敗しているデータを調べたところ、対象レコードにNUL(\00)文字が含まれていたようだった。そこで、Sqoopの内部動作を追いながら回避方法を模索してみた。

テスト環境

今回の動作テストの環境は以下の通り。

  • sqoop-1.4.5-cdh5.3.3
  • ローカル環境

Sqoop Process Overview

まず、Sqoopの実行プロセス概要は以下のようになっている。RDBMSとHDFS間のデータ転送はMapReduceジョブで(Mapタスク)並列実行される。Mapタスクの数などはオプションで調整することができる。

sqoop-proess

Generated Sqoop ORM Class

Sqoopは、実行時にデータ転送のためのORMクラスを生成する。Sqoop Exportを実行してMySQLへデータ転送する例を挙げ、どのようなORMクラスが生成されるのかを見てみる。

まずは、以下のようなテーブルをMySQLに準備する。

続いてexportコマンドでORMクラスの生成及びexport処理を実行してみる。今回は、ローカル環境でコマンドラインでなくIDE上でJavaから直接Sqoopクラスをコールする形で実行した。

実行するとoutputディレクトリに以下のファイルが生成される。

employee.javaがORMクラスになり中身は以下のとおり。

Export処理でのエラーを探る

今回エラーとなったNUL文字を含むデータとして以下のようなサンプルデータを用意した。^A^@は制御コードを示している。

入力データ

レコードのparse

ソースの中でExceptionがスローされたのは以下の箇所。ソース中のコメントにも書いているが、レコードを行単位で処理していく(入力データは標準的なテキストファイルを想定)際にレコードをparseしてフィールドのリストとして返すところで、メソッドから返されたリストの要素数がテーブルメタ情報から取得したカラム数と一致していないことでエラーとなっていたもよう。__loadFromFieldsメソッドでIteratorを使って要素にアクセスするが、リストのフィールド数がカラム数より小さいため、リストの終端を超えた要素アクセスが発生しjava.util.NoSuchElementExceptionがスローされている。

さらに、RecordParser#parseRecordを追ってみる。parseRecordはステートマシンで実装されており、行レコードをパースしてフィールドのリストに分解する。以下は、メソッドの処理を簡略化したものになる。

上記のステートマシンの状態遷移図を書くと以下のようになるだろうか。

この状態遷移図をもとに、今回ParseErrorとなったレコードの遷移を見てみる。

NUL文字はenclosingCharのデフォルト値として使われているため、今回のようにレコードにNUL文字が含まれていた場合、本来FILED_START -> UNENCLOSED_FIELDと遷移することを期待していたが、FIELD_STARTの状態時にENCLOSED_FIELDに遷移する入力(enclosingCharトークン)が出現したため期待と異なる状態へ遷移してしまっていた。この結果、最終的にListとして返されたデータは以下のようになっていた。

不正文字を含むレコードのParseErrorへの対処

ORMクラス内で文字列置換

なかなか難儀だが、自動生成されたORMクラス内でparseRecordされる前に置換する方法。修正したソースを事前にコンパイルして、exportやimportコマンド実行時に--jar-fileオプションで渡してやる。

enclosingChar、escapeCharの変更

もう1つは、極力sqoopの範囲で対応してあげる方法があるだろうか。デフォルトではNUL文字となっているenclosingCharやescapeCharを処理上影響のない文字に変更する。Exportの場合は、--input-escaped-by--input-optionally-enclosed-byで指定できる。例えば以下のようになる。

実行するとmysqlには以下のようにデータが入っていることが確認できた。

例えば、RDBMSからHDFSへ--hive-drop-import-delimsオプション付きでhiveインポートして、さらに別のサービスで同テーブルデータを使いたくexportするような場合には、--hive-drop-import-delimsでドロップされた文字を--input-escaped-byなどのオプションに渡してあげれば、export時にドロップされた文字が出現しないことが保証されるだろう。

https://sqoop.apache.org/docs/1.4.5/SqoopUserGuide.html#_importing_data_into_hive

ということで、レコード内にsqoopのパースに影響のある文字列が含まれる場合は注意する。事前に不正な文字列が除去できているのが望ましいと思う。

参考リンク

  • https://sqoop.apache.org/docs/1.4.5/SqoopUserGuide.html
Hadoop 第3版

Hadoop 第3版

posted with amazlet at 16.07.17
Tom White
オライリージャパン
売り上げランキング: 246,670

Install Cloudera Manager with Ansible

この記事は【2016年7月3日】と作成から2年以上経っているため、記事の内容が古い可能性があります。最新の情報を合わせてご確認されることを推奨いたします。

Cloudera Managerを使って本番用のHadoopクラスタ環境を構築して運用している。アップデート時など調査・検証のためテスト環境を度々繰り返し構築しなおすことがあるため、ある程度構築を自動化しておきたいと思い、今回Ansibleを使ってCloudera Managerのインストールから起動までの手順を書いてみた。

構成

構成は以下の通り。

  • MySQL 5.6
  • Cloudera Manager 5.x
  • CentOS6
  • Running on a Virtual Machine with Vagrant

ディレクトリ構成

mysql-connector-javaは、事前に以下のページからダウンロードして配置しておく。

http://dev.mysql.com/downloads/connector/j/5.1.html

各種設定

Vagrantfile

vagrant.yml

cdh.yml

vansible.sh

これは、vagrantマシンへのアクセスを簡易化するためのただのスクリプト。

templates

cloudera-manager.repo

cm_versionからfilterを使ってバージョン指定している。

dot.my.cnf

vars

main.yml

以下例でパスワードを平文で設定ファイルに書いているが、必要に応じてansible-vaultで暗号化しておく。

tasks

main.yml

Cloudera Managerのインストール手順については、公式ドキュメントの『Installation Path B – Manual Installation Using Cloudera Manager Packages』のセクションを参照。

実行

無事起動できたら、以下のリンクにアクセスするとCloudera Managerのログイン画面が表示される。

http://localhost:7180/

cloudera-manager-login

参考リンク

  • http://www.cloudera.com/documentation/enterprise/5-5-x/topics/installation_installation.html
  • https://github.com/ymc-geko/ansible-cdh-cluster
  • https://dev.mysql.com/doc/refman/5.6/ja/linux-installation-yum-repo.html
  • http://qiita.com/KisaragiZin/items/e241f189c83580f92e9c
  • http://docs.ansible.com/ansible/mysql_db_module.html

AnsibleのplaybookをVagrantでテストする

この記事は【2016年6月23日】と作成から2年以上経っているため、記事の内容が古い可能性があります。最新の情報を合わせてご確認されることを推奨いたします。

AnsibleのplaybookをテストをするのにVagrantで構築した仮想マシンを使っている。VagrantではProvisionerとしてAnsibleが利用可能であり以下のようにすればvagrant upでAnsibleのplaybookを実行することができる。

テストするときに様々なグループやロールごとに実行したい時もあり、その場合はVagrantfileの中で指定するのでなく、ansibleコマンドでplaybookのテストをするようにしている。

Vagrant環境で手動によるplaybookの実行

provisionでansibleを指定すると以下のパスにVagrant環境のinventoryファイルが生成される。このファイルにsshアクセスするのに必要な情報が鍵情報含めて定義されている。

あとは、上の定義をコマンドラインオプションで渡してあげれば、Vagrant上での容易にplaybookの実行が可能となる。

ホスト名やinventoryは毎回同じ値を指定することになるので、簡単なスクリプトを用意して実行している。

以下サンプル。

vansible.sh

vagrant.yml

web

db

Vagrantfile

vagrant-inventory。ここにグループを加えておく。

inventoryのマージ。

ansibleの実行。

参考リンク

  • http://docs.ansible.com/ansible/guide_vagrant.html
  • https://www.vagrantup.com/docs/provisioning/ansible.html
入門Ansible

入門Ansible

posted with amazlet at 16.06.23
(2014-07-30)
売り上げランキング: 3,212
初めてのAnsible

初めてのAnsible

posted with amazlet at 16.06.23
Lorin Hochstein
オライリージャパン
売り上げランキング: 25,752

JNIメモ1

この記事は【2016年6月16日】と作成から2年以上経っているため、記事の内容が古い可能性があります。最新の情報を合わせてご確認されることを推奨いたします。

Impalaという分散クエリエンジンを使っていてImpaladが突然JVMのSIGSEGVで異常終了してしまうことがありソースを追いかけている。ソースを読んでいるとJNI経由でC++の世界とJavaの世界との連携を行なっている部分があり、JNIについて知識が乏しかったので今回JNI(Java Native Interface)に関して自分なりに調べ以下備忘録としてまとめてみる。

JNI(Java Native Interface)

Javaの世界とC/C++の世界との間をつないでくれる。JavaとC/C++のようなネイティブで実行されるプログラム間で連携するためのインターフェース仕様。JavaからC/C++で書かれたプログラムを呼び出したり、逆にC/C++からJavaのオブジェクトを呼び出したりすることが可能。

Quick Start

まずは、簡単なサンプルを動かしてみて実行イメージをつかむ。

JavaからC/C++のプログラムを呼ぶ

以下のステップで実行する。

  1. nativeメソッドを定義し、javacでJavaプログラムをコンパイル
  2. javahコマンドでヘッダーファイル生成
  3. c/c++の実装部分を書く
  4. ダイナミックライブラリ(Shared library)を生成
  5. JavaからSystem.loadLibraryでダイナミックライブラリをロード
  6. 実行

まずは、nativeメソッド定義する。ここでは、引数に渡した文字列を出力する単純なサンプルを想定している。

続いてコンパイルする。

クラスファイルからjavahでヘッダファイルを生成する。

これにより生成されたファイルは以下のようになる。

メソッド名は、以下のような規則で構成されるらしい。

  • 接頭辞Java_
  • 分解された完全修飾クラス名
  • 下線 (「_」) 区切り文字
  • 分解されたメソッド名
  • オーバーロードされたネイティブメソッドでは、2 個の下線 (「__」) に続いて分解された引数のシグニチャー

続いて実装。C++で書くと多少ポインタ周りがスッキリする。各種関数がインラインメンバ関数として定義されているため(jni.h参照のstruct JNIEnv_を参照)

ダイナミックライブラリを作成する。

最後にJavaを実行して正常にロードされているか確認。

C/C++からJavaのプログラムを呼ぶ

続いて今度はC/C++からJavaのプログラムを呼び出す例を見てみる。基本的な流れは以下のようになるだろうか。

  1. VM作成
  2. クラス探索
  3. メソッドの呼び出し
  4. VM破棄

以下実際のソースで見てみる。ここでは、java.lang.Mathクラスのrandomメソッドを実行してみる。

続いてコンパイル。

なお、Macで実行した場合Java SE 6の環境がインストールされていないとダイアログが表示されて実行することができない。取り急ぎの実行に際しては、以下のリンクから過去のバージョンをダウンロードすることができる。

https://support.apple.com/kb/DL1572?viewlocale=en_US&locale=ja_JP

Type Mapping

JavaとC/C++の世界ではルールも異なればデータの型も異なる。したがって両者の間で型をどのように扱うのか、あらかじめ取り決めをしてやる必要がある。jni.hを参考にすると以下のようにマッピングされていることがわかる。

プリミティブ型

Javaの型 ネイティブの型 説明 Ex) jni.h / jni_x86.h
(OpenJDK9)
boolean jboolean unsigned 8bit unsigned char
byte jbyte signed 8bit signed char
char jchar unsigned 16bit unsigned short
short jshort signed 16bit short
int jint signed 32bit int
long jlong signed 64bit #if defined(_LP64)
long
#else
long long
#endif
float jfloat 32bit float
double jdouble 64bit double
void void

その他以下のようなタイプエイリアスやマクロが定義されている。

参照型

以下のような構造になっている。

Signature

JVMの型のシグネチャー表現は以下のようになっている。.classファイルを開くと見かける英数字や記号などのアレ。

以下jvm.hからの抜粋。