さくらVPSにchef-serverをインストールする



さくらVPSにchef-serverとchef-clientをインストールする」でchef-serverのインストールまで
たどりつかなかったので改めて、設定をしてみました。
Manual Chef Server Configuration」を元に、chef-serverをインストールしました。
 

CouchDBとRabbitMQをインストールする

yumから必要なソフトをインストールします。

 sudo yum install couchdb erlang rabbitmq-server libxml2-devel zlib-devel

 
couchdbは、memcachedを扱っている会社と合併した気がするので、今後どうなるのかなとふと思いました。
javaは、sun jdkが既にインストールされているので、除外しています。CouchDBをスタートします。

 $ sudo service couchdb start

 
任意の設定をしていると「http://hostname:5984」でバージョン情報がjson形式で受け取れます。

 {"couchdb":"Welcome","version":"0.11.2"}

 
http://hostname/_utilsにアクセスすると管理画面を確認することができます。

 
RabbitMQを開始します。

 $ sudo service rabbitmq-server start
 $ sudo rabbitmqctl add_vhost /chef
 $ sudo rabbitmqctl add_user chef testing
 $ sudo rabbitmqctl set_permissions -p /chef chef ".*" ".*" ".*"

 

gemからChef Serverをインストールする

gemを利用して、Chef Serverをインストールします。

 $ sudo gem install chef-server chef-server-api chef-solr chef-server-webui merb
 $ sudo gem install sqlite3-ruby -v 1.2.5
 $ gem list | grep chef
  chef (0.9.14)
  chef-server (0.9.14)
  chef-server-api (0.9.14)
  chef-server-webui (0.9.14)
  chef-solr (0.9.14)

 

起動のためのserver.rbを準備する。

「/etc/chef/server.rb」に「Configure Chef Server」の内容を元に準備します。

 log_level          :info
 log_location       STDOUT
 ssl_verify_mode    :verify_none
 chef_server_url    "http://chef.example.com:4000"
 
 signing_ca_path    "/var/chef/ca"
 couchdb_database   'chef'
 
 cookbook_path      [ "/var/chef/cookbooks", "/var/chef/site-cookbooks" ]
 
 file_cache_path    "/var/chef/cache"
 node_path          "/var/chef/nodes"
 openid_store_path  "/var/chef/openid/store"
 openid_cstore_path "/var/chef/openid/cstore"
 search_index_path  "/var/chef/search_index"
 role_path          "/var/chef/roles"
  
 validation_client_name "chef-validator"
 validation_key         "/etc/chef/validation.pem"
 client_key             "/etc/chef/client.pem"
 web_ui_client_name     "chef-webui"
 web_ui_key             "/etc/chef/webui.pem"
  
 web_ui_admin_user_name "admin"
 web_ui_admin_default_password "somerandompasswordhere"
 
 supportdir = "/srv/chef/support"
 solr_jetty_path File.join(supportdir, "solr", "jetty")
 solr_data_path  File.join(supportdir, "solr", "data")
 solr_home_path  File.join(supportdir, "solr", "home")
 solr_heap_size  "256M"
  
 umask 0022
 
 Mixlib::Log::Formatter.show_time = false

 
「chef_server_url」を任意のURLに変更します。「web_ui_admin_default_password」のパスワード値が少し長いので
任意のパスワード名に変更します。
 

Chef Indexer、Chef SOLR Server、Chef Serverを起動する。

Chef Indexer、Chef SOLR Server、Chef Serverをそれぞれ起動します。プログラムがフォアグラウンドで
起動されるので、「nohup command &」として起動しても良いと思います。

 $sudo chef-solr-indexer
  $sudo chef-solr
  $sudo chef-server -N -e production
  $sudo chef-server-webui -p 4040 -e production

 
「Chef Solr」は、Javaで動いているようでした。「Apache solr」が利用されているようで、起動オプションを
いろいろ設定できるようです。

Name Listen Port Example Program Name in ps (Erlang programs truncated)
Chef Solr 8983 /usr/bin/java -Xmx250M -Xms250M -Dsolr.data.dir=/opscode/chef/features/data/solr/data -Dsolr.solr.home=/opscode/chef/features/data/solr/home -jar /opscode/chef/features/data/solr/jetty/start.jar

 

起動後、管理画面を試す

無事起動ができると、Chef Serverのwebuiをブラウザから閲覧することができます。
http://hostname:4040/」でアクセスすると、ログイン画面が表示されるので、server.rbで設定した「web_ui_admin_user_name」「web_ui_admin_default_password」を利用してログインします。

 
管理画面から、userを追加したり、ノードの設定、cookbookの編集?など、いろいろできるようです。
 

今回はまったこと

今回、いろいろ理解が乏しく、結構、はまりました。そこで、何度かサービスを立ち上げたり、OSを再起動してみたのですが
それでもエラーが消えず、元からデータを削除してみたりしました。

 $rm -r /var/chef/

 
「/etc/chef/server.rb」によると、「file_cache_path」やら「search_index_path」やらがあったので
エラーの内容と関係あるのかわからずとりあえず消していました。
それでも、couchdbにログインできないuseridなどが消えなかったので、格納しているファイル自体消したりしました。
couchdbの管理画面から消してみたりはしてみたのだが、エラーが改善できなかったので最終手段)

 rm /var/lib/couchdb/chef.couch
 rm /var/log/couchdb/couch.log

 
chef.couchの中身は、jsonデータのようです。couch.logはログファイルですが、ついでに消しました。

次回は、なんとか「Hello World example」までたどり着いてcookbookを
利用してみたいとです。また、余力があれば「How to Proxy Chef Server with Apache」も試してみたいと思います。


さくらVPSにchef-serverとchef-clientをインストールする



さくらVPS環境で、‥その後、chef-soloをインストールしてみる」で、「openssl.so: undefined symbol」というエラーがでてしまい
途中で終わっていたので、インストールをやりきってみました。「How to Get Started」という記事を参考にしたのですが、
途中で、「Configure a server as a Chef client」というのもでてきてしまったので、ついでにchef-serverのインストールもしてみました。
 

目的

Amazon Web ServiceやVPS環境で似たような環境を構築する時に、手間をかけないであるていど構築できないかと
思い調べてみます。Puppetというツールもありますが、Ruby1.9で動かない?ようなので、chefの方を試してみます。*1

世間で流行っているみたいなので、ついでにどんなソフトを利用しているのか確認をしてみます。
 

前提

前提は、下記の通りです。

  • How to Get Started」を参考に環境を構築してみます。
  • 4. Setting Up a Chef Client」で「Configure a server」というものがでてきたのでついでにサーバ機能もインストールしてみた。
  • chefのインストールで終わっているので、使い方に関しては、まだ確認中です。

 

設定してみる

設定をしてみます。
 

openssl.soのエラーを解決しておく

さくらVPS環境で、‥その後、chef-soloをインストールしてみる」で、「openssl.so: undefined symbol」というエラーがでてしまったところは、下記のような感じで対処しました。

ruby extconf.rb --with-openssl-include=/usr/include --with-openssl-lib=/usr/lib

インストール後、irbで確認してみます。

 $ irb
  irb(main):001:0> require 'openssl'
  => true

 

「Create your Chef repository」を実施する

2. Setting Up Your User Environment」の記事を元に設定をおこなっていきます。

 $ cd ~
 $ git clone http://github.com/opscode/chef-repo.git
 $ mkdir -p ~/chef-repo/.chef
 $ cp USERNAME.pem ~/chef-repo/.chef
 $ cp ORGANIZATION-validator.pem ~/chef-repo/.chef
 $ cp knife.download ~/chef-repo/.chef/ knife.rb
 $ cd ~/chef-repo
 $ knife client list
  [
  "ORGANIZATION-validator"
  ]

 
knife.rbの中身はなにが書かれているか確認をしておきます。

 $ cat ~/chef-repo/.chef/knife.rb
  current_dir = File.dirname(__FILE__)
  log_level :info
  log_location STDOUT
  node_name "USERNAME"
  client_key "#{current_dir}/USERNAME.pem"
  validation_client_name "ORGANIZATION-validator"
  validation_key "#{current_dir}/ORGANIZATION-validator.pem"
  chef_server_url "https://api.opscode.com/organizations/USERNAME"
  cache_type 'BasicFile'
  cache_options( :path => "#{ENV['HOME']}/.chef/checksums" )
  cookbook_path ["#{current_dir}/../cookbooks"]

 

Cookbooksを取り込む

「3. Working with Cookbooks」の記事を元に、 「local chef-repo」にCookbooksを取り込みます。

 $ cd ~/chef-repo
 $ knife cookbook site vendor getting-started
 $ cd ~/chef-repo
 $ knife cookbook upload getting-started
 $ cd ~/chef-repo
 $ knife cookbook list
  [
   "getting-started"
  ]

 
とりあえず、意味半分くらいしか理解してませんが、取り込みができたみたいです。
 

workstationの設定をおこなってみます。

 $ cd ~/chef-repo
 $ knife configure client ./client-config
 $ ls -l client-config
  合計 8
  -rw-r--r-- 1 id work 153 4月 3 20:45 client.rb
  -rw-r--r-- 1 id work 1675 4月 3 20:45 validation.pem
 $ sudo chef-client
   [sudo] password for id:
   [Mon, 04 Apr 2011 19:27:24 +0900] INFO: Starting Chef Run (Version 0.9.14)
   [Mon, 04 Apr 2011 19:27:25 +0900] WARN: Node FQDN has an empty run list.
   [Mon, 04 Apr 2011 19:27:27 +0900] INFO: Chef Run complete in 2.528441 seconds
   [Mon, 04 Apr 2011 19:27:27 +0900] INFO: cleaning the checksum cache
   [Mon, 04 Apr 2011 19:27:27 +0900] INFO: Running report handlers
   [Mon, 04 Apr 2011 19:27:27 +0900] INFO: Report handlers complete
   $ knife node list
    [
     "FQDN"
    ]

 
なんとか記事の通りできたようです。
 

「Manual Chef Server Configuration」を実施する

Manual Chef Server Configuration」を元にChef Server機能を
インストールしようと思いましたが、少し長くなりましたので、次回に続こうと思います。
 


*1:きちんと調べてないので嘘書いてるかも。

Cassandra 0.7.4でColumnFamilyのキーを取得する。



Cassandraのメーリングリストで「userアットcassandra.apache」というのがあります。
そこの投稿で「newbie question: how do I know the total number of rows of a cf?」という質問があったので、調べてみました。
 
質問の回答は

 1. run a map reduce. Pig is really helpful in these cases. Make sure you run your MR using Hadoop task tracker on your nodes - or your performance will take a hit.
 2. dump all keys using sstablekeys script from relevant files on all machines and count unique values. I do that using "sort -n  keys.txt |uniq >> unique_keys.txt"

とか

 sort -n keys.txt | uniq | wc -l

とあるのだが、keys.txtはどうやって出力するのか調べてみました。
 
Cassandraのbinディレクトリをみると「bin/sstablekeys」というのがある。
ついでに、「/bin/sstable2json」というのもある。

とりあえず、実行してみた。

 Usage: sstablekeys <sstable>

 
というものを指定しないといけないらしい。とはなんだろう?
sstablekeysの中身をみてみると

if [ "x$CASSANDRA_INCLUDE" = "x" ]; then
    for include in /usr/share/cassandra/cassandra.in.sh \
                   /usr/local/share/cassandra/cassandra.in.sh \
                   /opt/cassandra/cassandra.in.sh \
                   ~/.cassandra.in.sh \
                   /usr/local/cassandra/bin/cassandra.in.sh \
                   `dirname $0`/cassandra.in.sh; do
        if [ -r $include ]; then
            . $include
            break
        fi
    done
elif [ -r $CASSANDRA_INCLUDE ]; then
    . $CASSANDRA_INCLUDE
fi

 
cassandra.in.shのありかを指定しないといけないらしいので「/usr/local/cassandra/bin/cassandra.in.sh \」を追加してみました。
「./bin/sstablekeys Keyspace1」を実行してみると、

 Exception in thread "main" java.util.NoSuchElementException
        at java.util.StringTokenizer.nextToken(StringTokenizer.java:332)
        at org.apache.cassandra.io.sstable.Descriptor.fromFilename(Descriptor.java:139)
        at org.apache.cassandra.io.sstable.Descriptor.fromFilename(Descriptor.java:119)
        at org.apache.cassandra.tools.SSTableExport.enumeratekeys(SSTableExport.java:271)
        at org.apache.cassandra.tools.SSTableExport.main(SSTableExport.java:462)

とでてしまいました。
 
org.apache.cassandra.tools.SSTableExportのソース462行目を読んでみる。enumeratekeys(ssTableFileName, System.out);というメソッドがあるみたい。
実装を確認してみます。

    public static void enumeratekeys(String ssTableFile, PrintStream outs)
    throws IOException
    {
        Descriptor desc = Descriptor.fromFilename(ssTableFile);
        KeyIterator iter = new KeyIterator(desc);
        DecoratedKey lastKey = null;
        while (iter.hasNext())
        {
            DecoratedKey key = iter.next();

            // validate order of the keys in the sstable
            if (lastKey != null && lastKey.compareTo(key) > 0 )
                throw new IOException("Key out of order! " + lastKey + " > " + key);
            lastKey = key;

            outs.println(bytesToHex(key.key));
        }
        iter.close();
        outs.flush();
    }

 
標準出力にssTableFileというものをだしているっぽい。多分。
「/var/lib/cassandra/data/Keyspace1/」にStandard2-f-1-Index.dbというファイルがあるので
指定して実行してみました。

 $ ./bin/sstablekeys /var/lib/cassandra/data/Keyspace1/Standard2-f-1-Index.db
   6d69636869626174616a65737369636133
   736173616b696e6f7a6f6d69
   736173616b696e6f7a6f6d6933

なんかそれっぽいのがでました。
「./bin/sstable2json /var/lib/cassandra/data/Keyspace1/Standard2-f-1-Index.db」も試してみました。

 $ ./bin/sstable2json /var/lib/cassandra/data/Keyspace1/Standard2-f-1-Index.db
 {
"6d69636869626174616a65737369636133": [["616765", "3235", 1300717063585, false], ["6669727374", "4a657373696361", 1300717063585, false], ["6c617374", "4d6963686962617461", 1300717063585, false]],
"736173616b696e6f7a6f6d69": [["616765", "3232", 1300716830310000, false], ["6669727374", "6e6f7a6f6d69", 1300716779268000, false], ["6c617374", "736173616b69", 1300716823681000, false]],
"736173616b696e6f7a6f6d6933": [["616765", "3232", 1300717063585, false], ["6669727374", "6e6f7a6f6d69", 1300717063585, false], ["6c617374", "736173616b69", 1300717063585, false]]
}

それっぽいデータがまたでました。
 
「Standard2-f-1-Data.db」「Standard2-f-1-Filter.db」「Standard2-f-1-Statistics.db」でもそれぞれ
同じようにキーが出力されるみたいです。


さくらVPS環境で、ruby-1.9.2-p0とRails3をインストールする。その後、chef-soloをインストールしてみる。



LinuxにRuby1.9.2とRails3をインストール」を参考にRuby1.9.2とRails3をインストールしました。さくらVPS上で、chef-soloを試しに使ってみたかったので、うまくいくか試してみました。chef-soloに関しては、「chef-soloで作業環境構築の自動化」を参考にしました。
 

ruby-1.9.2をインストールする

ruby1.9のソースをダウンロードし、インストールします。

 $cd /usr/local/src/
 $wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-p0.tar.gz
 $tar zxvf ruby-1.9.2-p0.tar.gz
 $cd ruby-1.9.2-p0
 $./configure
 $make 
 $make install
  installing binary commands:   /usr/local/bin
  installing base libraries:    /usr/local/lib
  installing arch files:        /usr/local/lib/ruby/1.9.1/x86_64-linux
  installing extension objects: /usr/local/lib/ruby/1.9.1/x86_64-linux
  installing extension objects: /usr/local/lib/ruby/site_ruby/1.9.1/x86_64-linux
  installing extension objects: /usr/local/lib/ruby/vendor_ruby/1.9.1/x86_64-linux
  installing extension headers: /usr/local/include/ruby-1.9.1/x86_64-linux
  installing extension scripts: /usr/local/lib/ruby/1.9.1
  installing extension scripts: /usr/local/lib/ruby/site_ruby/1.9.1
  installing extension scripts: /usr/local/lib/ruby/vendor_ruby/1.9.1
  installing extension headers: /usr/local/include/ruby-1.9.1/ruby
  installing rdoc:              /usr/local/share/ri/1.9.1/system
  installing capi-docs:         /usr/local/share/doc/ruby
  installing command scripts:   /usr/local/bin
  installing library scripts:   /usr/local/lib/ruby/1.9.1
  installing common headers:    /usr/local/include/ruby-1.9.1
  installing manpages:          /usr/local/share/man/man1
  installing default gems:      /usr/local/lib/ruby/gems/1.9.1 (cache, doc, gems, specifications)
                              rake 0.8.7
                              rdoc 2.5.8
                              minitest 1.6.0

 
インストールしたものが動くかどうか試してみました。

 gem list
 
 *** LOCAL GEMS ***
 
 minitest (1.6.0)
 rake (0.8.7)
 rdoc (2.5.8)

 

sqlite3-rubyをインストールする

sqlite3をgemからインストールします。

 gem i sqlite3-ruby

 
参考にしたページと同じところでsqliteのインストールがエラーとなりました。
rpm管理下の方がなにかと都合が良いので、checkinstallを利用してみます。

 $cd /usr/local/src/
 $wget http://asic-linux.com.mx/~izto/checkinstall/files/source/checkinstall-1.6.2.tar.gz
 $tar zxvf checkinstall-1.6.2.tar.gz
 $cd checkinstall-1.6.2.tar.gz
 $make install
 
  $pwd
  /usr/local/src/checkinstall-1.6.2
  $/usr/local/sbin/checkinstall
  $/usr/src/redhat/RPMS/x86_64
  $rpm -i checkinstall-1.6.2-1.x86_64.rpm

 
きちんとインストールされているか確認をしてみます。

 $yum list checkinstall
   Installed Packages
   checkinstall.x86_64                                                                      1.6.2-1                                        installed                            

 
sqlite3をビルドしてrpmにしてインストールしてみます。sqlite3インストール後、そのままrailsをインストールします。

 $cd /usr/local/src/
 $wget http://www.sqlite.org/sqlite-amalgamation-3.7.2.tar.gz
 $tar zxvf sqlite-amalgamation-3.7.2.tar.gz
 $cd sqlite-3.7.2
 $./configure
 
 $/usr/local/sbin/checkinstall
 $cd /usr/src/redhat/RPMS/x86_64/
 $rpm -i sqlite-3.7.2-1.x86_64.rpm
 
 $gem i sqlite3-ruby
 
 $gem i rails

 

動作確認をしてみる

railsコマンドで新しいプロジェクトを作成します。blogというディレクトリが作成されます。

 rails new blog
 
 rails c 
 /usr/local/lib/ruby/1.9.1/irb/completion.rb:9:in `require': no such file to load -- readline (LoadError)

 
rails c」を試してみると、エラーがでました。「readline」が足りないみたいです。

 $yum install readline-devel
 $cd /usr/local/src/ruby-1.9.2-p0/ext/readline
 $ruby extconf.rb
  $make
  $make install
  $ruby -r readline -e ""
 #エラーがでてない。

 
WEBrickサーバを実行してみます。rails new blogを実行したディレクトリまで移動し、「rails s -p 3001」を実行します。

 netstat -anp | grep 3000
 tcp        0      0 0.0.0.0:3000                0.0.0.0:*                   LISTEN      766/java
 rails s -p 3001

 
iptablesなどの任意の設定をし、ブラウザからアクセスできることを確認しました。

 http://ipaddress:3001/

 

chef-soloをインストールする

chef-soloで作業環境構築の自動化」を参考にし、gemからインストールを
行います。

 gem install chef --no-rdoc --no-ri
 Building native extensions.  This could take a while...
 Successfully installed mixlib-config-1.1.2
 Successfully installed mixlib-cli-1.2.0
 Successfully installed mixlib-log-1.3.0
 Successfully installed mixlib-authentication-1.1.4
 Successfully installed json-1.4.6
 Successfully installed extlib-0.9.15
 Successfully installed systemu-1.2.0
 Successfully installed ohai-0.5.8
 Successfully installed rest-client-1.6.1
 Successfully installed bunny-0.6.0
 Successfully installed moneta-0.6.0
 Successfully installed highline-1.6.1
 Successfully installed uuidtools-2.1.2
 Successfully installed chef-0.9.14
 14 gems installed

 
とりあえず、よく分からないので「Chefリポジトリのひな形をGitHubからいただいて来て設定ファイルを作る。」を
そのまま実行してみます。

 $ git clone git://github.com/opscode/chef-repo.git
 $ cd chef-repo
 $ mkdir .chef

  .chef/solo.rb
    file_cache_path "/tmp/chef-solo"
    cookbook_path "/home/akahige/chef-repo/cookbooks"
  .chef/chef.json
    {
     "run_list": [ "recipe[base_packages]" ]
    }

 
chef-soloを実行してみます。

 $chef-solo -c .chef/solo.rb -j .chef/chef.json
  <internal:lib/rubygems/custom_require>:29:in `require': /usr/local/lib/ruby/site_ruby/1.9.1/x86_64-linux/openssl.so: undefined symbol: d2i_ECPKParameters -  
   /usr/local/lib/ruby/site_ruby/1.9.1/x86_64-linux/openssl.so (LoadError)

 
いろいろ試してみたが、openssl.soのエラーがとれなかったので、引き続き課題にできればと思います。
ruby1.8.7 もインストールされており、その影響があるかもしれないので、もう一度、きれいな環境を作ってみたいと思います。)


Amazon EC2 (Asia Pacific 東京)でm1.large を利用して、Cassandra 0.7.4のストレステストを試す。



前回、マイクロ インスタンスを利用して、Cassandra 0.7.4のストレステストを試してみました。あまり期待した結果がでなかった
為、今回は、ラージ インスタンスで試してみたいと思います。スモール インスタンスも検討したのですが、32bitしか
サポートしていなかった為、64bitサポートがあるラージ インスタンスにしてみました。
 

前回の補足で、swap領域を追加してみる

swap領域が無かった為、物理メモリの上限を超えたあたりで、ストレステストのプログラムをkillされて
しまったが、swap領域を新たに確保し、t1.microとm1.largeでストレステストを実施してみた。

m1.largeにおいて、確保したswap領域は、以下の通りです。t1.microに関しては、1G程増やして
試してみました。

 $dd if=/dev/zero of=/swap bs=1G count=2
  2+0 records in
  2+0 records out
  2147483648 bytes (2.1 GB) copied, 5.03326 seconds, 427 MB/s
  $mkswap /swap
    Setting up swapspace version 1, size = 2147479 kB
  $swapon /swap
  $swapon -s
    Filename                                Type            Size    Used    Priority
    /swap                                   file            2097144 0       -1
  $cat /proc/swaps
    Filename                                Type            Size    Used    Priority
    /swap                                   file            2097144 0       -1
  $free -m
                  total       used       free     shared    buffers     cached
    Mem:          7680       2315       5364          0          5       2082
    -/+ buffers/cache:        226       7453
    Swap:         2047          0       2047

 
ストレステスト実施中のOSリソースの確認は、sarコマンドで行いました。

m1.largeにおける実施内容は、下記のような感じでした。t1.microでは、OOM Killerは
起こらなかった物のstealが常に100%近くなり、ストレステスト自体がなかなか終わりませんでした。

 17時08分54秒       CPU     %user     %nice   %system   %iowait    %steal     %idle
 17時08分55秒       all      2.99      0.00      0.50      0.00      0.50     96.02
 17時08分56秒       all      1.01      0.00      0.00      0.00      0.00     98.99
 17時08分57秒       all      1.00      0.00      0.50      0.00      0.00     98.51
 17時08分58秒       all      5.05      0.00      0.00      0.00      0.00     94.95
 17時08分59秒       all      0.51      0.00      0.00      0.00      0.00     99.49
 17時09分00秒       all      0.99      0.00      0.00      0.00      0.00     99.01
 17時09分01秒       all      0.49      0.00      0.49      0.00      0.00     99.01
 17時09分02秒       all      0.50      0.00      0.00      0.00      0.50     99.01
 17時09分03秒       all      0.51      0.00      0.00      0.00      0.00     99.49
 17時09分04秒       all      0.49      0.00      0.49      0.00      0.00     99.01
 
 17時09分26秒       all      0.00      0.00      0.00      0.00      0.00    100.00
 17時09分27秒       all      0.00      0.00      0.00      0.00      0.00    100.00
 17時09分28秒       all      0.50      0.00      0.00      0.00      0.00     99.50
 17時09分29秒       all      5.00      0.00      0.00      0.00      0.00     95.00
 17時09分30秒       all      1.00      0.00      0.50      0.00      0.00     98.51
 17時09分31秒       all      3.43      0.00      0.49      0.00      0.00     96.08
 17時09分32秒       all     11.62      0.00      0.00      0.00      0.51     87.88
 17時09分33秒       all      0.50      0.00      0.00      0.00      0.00     99.50
 17時09分34秒       all      1.99      0.00      0.50      0.00      0.00     97.51

 

Cassandra 0.7.4のストレステストプログラムのコンパイル

apache-cassandra-0.7.4-srcをダウンロードし展開すると、「contrib/stress」というディレクトリがあります。
この中に、javaで書かれたストレスプログラムがあります。ちなみに「contrib/py_stress」というPython版も
あります。

javaとantが利用できることを確認します。

 $java -version
  java version "1.6.0_24"
  Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
  Java HotSpot(TM) 64-Bit Server VM (build 19.1-b02, mixed mode)
 $ant -version
    Apache Ant(TM) version 1.8.2 compiled on December 20 2010

 
antタスクを実行します。

 ant
  Buildfile: /usr/local/apache-cassandra-0.7.4-src/contrib/stress/build.xml
  
  init:
   
  build:
     [javac] /usr/local/apache-cassandra-0.7.4-src/contrib/stress/build.xml:34: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
  
  BUILD SUCCESSFUL
  Total time: 0 seconds

 
コンパイルが成功したらjarファイルを作成します。

 ant jar
  Buildfile: /usr/local/apache-cassandra-0.7.4-src/contrib/stress/build.xml
  
  init:
  
  build:
     [javac] /usr/local/apache-cassandra-0.7.4-src/contrib/stress/build.xml:34: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
  
  jar:
  
  BUILD SUCCESSFUL
  Total time: 0 seconds
 
 ls ./build
  classes  stress.jar

 
buildディレクト配下に、stress.jarができました。
stress.jarをクラスパスに設定してストレステストプログラムを実行します。

 contrib/stress/bin/stress -d xxx.xxx.xxx.xxx
 や
 contrib/stress/bin/stress -d xxx.xxx.xxx.xxx -o read --num-keys=500000
 contrib/stress/bin/stress -d 59.106.185.203 -n 5000000

といった使い方ができるみたいです。


Amazon EC2でCassandra 0.7.4をインストールし、実行する



Cassandraを複数のノードで試そうと思ったが、VPSサービスをいくつか契約する必要があり
性能的にどれがよいのか分からなかったのでとりあえず、Amazon EC2で試してみることにしました。
ここでいろいろストレステストや癖を試してみて、さくらVPSで運用できそうだったらさくらVPSの1.5 G版
か4 G版を検討してみたいとおもいます。*1
 

前提

    参考:「AWSの概要と登録手順〜Amazon EC2/S3環境構築のすべて〜

    参考:「Amazon EC2を操作するコマンドラインツール*2
    実行環境では、3月24日時点でダウンロードできる「ec2-api-tools-1.4.1.2」を利用しました。
    Amazon EC2 API Toolsからダウンロードできます。

  • private keyがコマンド作業環境に保存されていること

    参考:「インスタンス起動に必要となる設定

 

利用できるAMIイメージ(Amazon Machine Image)がないかどうか探してみる

「ec2-describe-images -x all」を利用すると、「公開イメージの一覧を表示」を取得することができます。
ただ、利用したいイメージがあるか分からないので、「ec2-describe-images --region ap-northeast-1 -x all | grep CentOS
」とコマンドを実行してみます。

$ec2-describe-images --region ap-northeast-1 -x all | grep CentOS
 IMAGE   ami-96e84297    411009282317/RightImage_CentOS_5.4_x64_v5.6.28_EBS      411009282317    available       public          x86_64  machine aki-a409a2a5    ari-a009a2a1            ebs     paravirtual     xen
 IMAGE   ami-a8eb41a9    644846711624/CentOS_5_4_i386_v5_6_8_1_EBS       644846711624    available       public          i386    machine aki-a209a2a3    ari-9e09a29f            ebs     paravirtual     xen
 IMAGE   ami-beeb41bf    644846711624/CentOS_5_4_x64_v5_6_8_1_EBS        644846711624    available       public          x86_64  machine aki-a409a2a5    ari-a009a2a1            ebs     paravirtual     xen
 IMAGE   ami-7605ae77    aoi-ami-jp/CentOS_5.2_x64_V1.manifest.xml       367998583407    available       public          x86_64  machine aki-a409a2a5    ari-a009a2a1            instance-store  paravirtual     xen
 IMAGE   ami-2a0ea52b    411009282317/RightImage CentOS5_2_X86_64_V4_1_10        411009282317    available       public          x86_64  machine aki-da09a2db                    instance-store  paravirtual     xen
 IMAGE   ami-300ea531    411009282317/RightImage CentOS_5.2_i386_v4.2.4  411009282317    available       public          i386    machine aki-a209a2a3    ari-9e09a29f            instance-store  paravirtual     xen
 IMAGE   ami-360ea537    411009282317/RightImage CentOS_5.2_x64_v4.2.4   411009282317    available       public          x86_64  machine aki-a409a2a5    ari-a009a2a1            instance-store  paravirtual     xen
 IMAGE   ami-3c0ea53d    411009282317/RightImage CentOS_5.4_i386_v4.4.10 411009282317    available       public          i386    machine aki-a209a2a3    ari-9e09a29f            instance-store  paravirtual     xen
 IMAGE   ami-480ea549    411009282317/RightImage CentOS_5.4_x64_v4.4.10  411009282317    available       public          x86_64  machine aki-a409a2a5    ari-a009a2a1            instance-store  paravirtual     xen
 IMAGE   ami-ce0ea5cf    411009282317/RightImage_CentOS_5.4_i386_v5.5.9  411009282317    available       public          i386    machine aki-a209a2a3    ari-9e09a29f            instance-store  paravirtual     xen
 IMAGE   ami-aee842af    411009282317/RightImage_CentOS_5.4_i386_v5.6.28 411009282317    available       public          i386    machine aki-a209a2a3    ari-9e09a29f            instance-store  paravirtual     xen
 IMAGE   ami-760ea577    411009282317/RightImage_CentOS_5.4_x64_v5.5.9   411009282317    available       public          x86_64  machine aki-a409a2a5    ari-a009a2a1            instance-store  paravirtual     xen
 IMAGE   ami-98e84299    411009282317/RightImage_CentOS_5.4_x64_v5.6.28  411009282317    available       public          x86_64  machine aki-a409a2a5    ari-a009a2a1            instance-store  paravirtual     xen

 
リージョン(--region)もオプションで指定してますが、「ec2-describe-regions」というコマンドで利用できるリージョン一覧を確認することができます。

REGION  eu-west-1       ec2.eu-west-1.amazonaws.com
REGION  us-east-1       ec2.us-east-1.amazonaws.com
REGION  ap-northeast-1  ec2.ap-northeast-1.amazonaws.com
REGION  us-west-1       ec2.us-west-1.amazonaws.com
REGION  ap-southeast-1  ec2.ap-southeast-1.amazonaws.com

 
結果一覧の「ap-northeast-1」が日本を表しているので、今回は日本リージョンを利用することとします。*3

立ち上げる仮想マシーンのタイプも検討する必要があります。「利用可能なインスタンスタイプ
をみるといろいろあることがわかります。

No インスタンス CPU Mem Disk arch
1 スモール インスタンス(デフォルト) 1 EC2 Compute Unit 1.7 GB 160 GB インスタンスストレージ (150 GB + 10 GB ルートパーティション) 32bit
2 ラージ インスタンス 4 EC2 Compute Unit(2仮想コア) 7.5 GB 850 GB インスタンスストレージ (2×420 GB + 10 GB ルートパーティション) 64bit
3 エクストララージ インスタンス 8 EC2 Compute Unit(4仮想コア) 15 GB 1,690 GB インスタンスストレージ (4×420 GB + 10 GB ルートパーティション) 64bit
4 マイクロ インスタンス 最大 2 EC2 Compute Unit 613 MB EBS ストレージのみ 32bit or 64bit

 
他にも「ハイCPU インスタンス」や「クラスターコンピュート インスタンス」、「クラスタGPU インスタンス」なども
あるみたいです。詳しくは、Amazon EC2 インスタンスタイプをご覧ください。

今回は、「instance-type」として、t1.micro(マイクロ インスタンス)を利用したいと思います。
マイクロ インスタンスは、「EBS ストレージのみ」のサポートなので、「ec2-describe-images」コマンドで参照した
AMIの内、「instance-store」ではなく、「ebs」を利用しなければいけません。*4

 

セキュリティグループの作成

立ち上がったインスタンスへのアクセス制限をする為に、ポートの設定をします。インスタンス立ち上げ時に何も
指定しないとdefaultというグループが設定されます。新しいグループを作成し、SSH(22番ポート)HTTP(80番ポート)
の設定をします。

 ec2-add-group grp-cent-test --description cent_security_group --region ap-northeast-1
 
 ec2-authorize grp-cent-test -p 22 --region ap-northeast-1
 ec2-authorize grp-cent-test -p 80 --region ap-northeast-1

 
設定したセキュリティグループを確認します。

 ec2-describe-group --region ap-northeast-1
 
 GROUP   sg-963a8d97     43**********    grp-centos-test centos_security_group
 PERMISSION      43**********    grp-centos-test ALLOWS  tcp     22      22      FROM    CIDR    0.0.0.0/0       ingress
 PERMISSION      43**********    grp-centos-test ALLOWS  tcp     80      80      FROM    CIDR    0.0.0.0/0       ingress

 

インスタンスの起動

今まで設定した内容を元にインスタンスを実行します。

No インスタンス リージョン インスタンスタイプ セキュリティグループ
1 CentOS_5_4_x64_v5_6_8_1_EBS ap-northeast-1 t1.micro grp-centos-test

 

 ec2-run-instances ami-beeb41bf --region ap-northeast-1 --instance-type t1.micro --group grp-fedora-test --monitor -k fedora_test_jp

 
インスタンスの実行後、若干、立ち上がりに時間がかかりますが、数分後、以下のコマンドで実行されていることを確認します。

 ec2-describe-instances --region ap-northeast-1

 
ステータスが「running」となっていれば、インスタンス構築の完了です。
  

インスタンスにログインしてみる

ec2-describe-instancesで確認した時に表示されていたドメインネームを利用して、ssh経由でインスタンスにログインします。

ssh -i fedora_test_jp.id root@ec2-1**-4*-2**-43.ap-northeast-1.compute.amazonaws.com

 

CentOS上に、Cassandraを構築する。

念のため、OSのバージョンを確認します。

 cat /etc/redhat-release
  CentOS release 5.4 (Final)

 
Javaをインストールし、Cassandraをインストールして、立ち上げます。
一瞬、はまった箇所といえば、conf/cassandra.yamlのlisten_address:にグローバルIPを設定したら下記のような
エラーログが出力されました。

ERROR [main] 2011-03-23 04:31:36,356 AbstractCassandraDaemon.java (line 196) Fatal configuration error
org.apache.cassandra.config.ConfigurationException: Unable to bind to address /1**.4**.2**.4**:7000. Set listen_address in cassandra.yaml to an interface you can bind to, e.g., your private IP address on EC2
        at org.apache.cassandra.net.MessagingService.listen(MessagingService.java:176)
        at org.apache.cassandra.service.StorageService.joinTokenRing(StorageService.java:424)
        at org.apache.cassandra.service.StorageService.initServer(StorageService.java:404)
        at org.apache.cassandra.service.AbstractCassandraDaemon.setup(AbstractCassandraDaemon.java:192)
        at org.apache.cassandra.service.AbstractCassandraDaemon.activate(AbstractCassandraDaemon.java:314)
        at org.apache.cassandra.thrift.CassandraDaemon.main(CassandraDaemon.java:79)

 
どこで、確認しているか分かりませんが、「on EC2」と実行環境を判別することができるようです。
 

stressテスト用のJavaを実行してみる

apache-cassandra-0.7.4-src内に「contrib/stress/bin/stress」というスクリプトがあります。
このスクリプトを利用して、さくらVPSとstressの結果を比較してみたいと思います。

EC2上で実施すると下記のようなエラーがでました。

 contrib/stress/bin/stress: line 49:  6196 強制終了            $JAVA -server -cp $CLASSPATH org.apache.cassandra.contrib.stress.Stress $@

 
OOM killerっぽい挙動かな?と思いメモリを確認してみるとSwapが0なのでした。

free -m
             total       used       free     shared    buffers     cached
Mem:           622         81        540          0          0          8
-/+ buffers/cache:         72        549
Swap:            0          0          0

 
このまま実行できないのもアレなので、memory overcommitを少しいじってみました。

 $cat /proc/sys/vm/overcommit_memory
  0
 $vi /etc/sysctl.conf
   vm.overcommit_memory = 1
   vm.overcommit_ratio = 99
  $/sbin/sysctl -p
  $cat /proc/sys/vm/overcommit_memory
   1

 
再度、実行してみると、若干うごきました。

 # contrib/stress/bin/stress -d 10.146.89.114
  Keyspace already exists.
  total,interval_op_rate,interval_key_rate,avg_latency,elapsed_time
  20319,2031,2031,0.002240710664894926,45
  56004,3568,3568,0.002166932884965672,96
  contrib/stress/bin/stress: line 49:  6196 強制終了            $JAVA -server -cp $CLASSPATH org.apache.cassandra.contrib.stress.Stress $@

 
結局、実行することができなかったので、次は、「Small Instance」あたりで試してみようと思います。
 


*1:ただ、ランニングコストとしては安くはないのですが・・。

*2:ファイアーウォール環境だとうまく動作しないかもしれません

*3:課金量がよく分かってないのでご利用は計画的に…

*4:正確には違うかもしれませんが、今はその認識ですすめてます。

JavaSE 6によるJMXの管理と、Attach APIの使い方



JMXによる「Java VMの健康管理」と「Attach API」について調べてみたことを記していきたいと思います。
JMXに関しては、あまりインターネットのブログ等で資料をみつけることができなかったので、
JavaSE 6のJava SE 監視および管理ガイド「第 2 章 JMX テクノロジを使用する監視と管理」を参考にしました。
Attach APIに関しては、ITproさんの「第10回 オンデマンドアタッチを実現するAttach API」を参考にしました。*1

Attach APIは、なにかというと「Attach API」ガイドの内容を引用してみたいと思います。

Attach API は、Sun Microsystems拡張機能で、JavaTM 仮想マシンに添付メカニズムを提供します。Java 言語で書かれたツールは、この API を使用してターゲットの仮想マシンに添付し、そのツールエージェントを仮想マシンにロードします。たとえば、管理コンソールに、仮想マシンの計測機構付きオブジェクトから管理情報を取得する管理エージェントが存在すると仮定します。管理コンソールは、管理エージェントのない仮想マシンで実行しているアプリケーションを管理する必要がある場合、この API を使用してターゲットの仮想マシンに添付し、エージェントをロードできます。

 

前提

  • JavaSE 6を利用している

 

JMXにアクセスできるようにServerとClientを実装してみる

第 2 章 JMX テクノロジを使用する監視と管理」を参考に忠実に実装してみました。*2
 

JMXにアクセスできるようにServerを実装してみる

MyApp.java

 System.setProperty("java.rmi.server.randomIDs", "true");
 System.out.println("Create RMI registry on port 3000");
 LocateRegistry.createRegistry(3000);
 
 // Retrieve the PlatformMBeanServer.
 //
 System.out.println("Get the platform's MBean server");
 MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();

 // Environment map.
 //
 System.out.println("Initialize the environment map");
 HashMap<String,Object> env = new HashMap<String,Object>();

 System.out.println("Create an RMI connector server");
 JMXServiceURL url =
     new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:3000/jmxrmi");
 JMXConnectorServer cs =
     JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);

 System.out.println("Start the RMI connector server");
 cs.start();

HashMap envを「JMXConnectorServerFactory.newJMXConnectorServer」の第二引数に渡して
いますが、単純なJMXConnectorServerを作成する場合は、nullで良いです。

実行してみると、下記のようにログを出力し、JMXクライアントからアクセスできる環境を構築することが
できました。

Create RMI registry on port 3000
Get the platform's MBean server
Initialize the environment map
Create an RMI connector server
Start the RMI connector server


jconsoleから試しに、アクセスしてみます。
リモートアクセスのサービス名に「service:jmx:rmi:///jndi/rmi://:3000/jmxrmi」を入力し、接続します。

 
うまく接続できると下記のような画面が表示されます。

 

JMXにアクセスできるようにClientを実装してみる

MyApp2.java

 // ロードしたエージェントがオープンした MBeanServer に接続
 
 JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:3000/jmxrmi");
 System.out.println("url="+url);
 
 JMXConnector connector = JMXConnectorFactory.connect(url, env);
 MBeanServerConnection connection = connector.getMBeanServerConnection();
 
 System.out.println("connector="+connector);
 System.out.println("connection="+connection);
 
 // MBeanServer から MXBean を取得
 MemoryMXBean memoryMXBean = ManagementFactory.newPlatformMXBeanProxy(
  connection,
  ManagementFactory.MEMORY_MXBEAN_NAME,
  MemoryMXBean.class);
  
 System.out.println("memoryMXBean="+memoryMXBean);
 
 // ヒープの使用量を出力
 MemoryUsage usage = memoryMXBean.getHeapMemoryUsage();
 System.out.println(usage);
 
 connector.close();

 
実行してみると、下記の様に表示されます。

 url=service:jmx:rmi:///jndi/rmi://:3000/jmxrmi
 connector=javax.management.remote.rmi.RMIConnector: jmxServiceURL=service:jmx:rmi:///jndi/rmi://:3000/jmxrmi
 connection=javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection@743399
 memoryMXBean=MXBeanProxy(javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection@743399[java.lang:type=Memory])
 init = 0(0K) used = 1504800(1469K) committed = 5177344(5056K) max = 66650112(65088K)

 

JMXにアクセスする際に、IDとパスワードを必須入力とする

MyApp側の実装

 HashMap<String,Object> env = new HashMap<String,Object>();
 env.put("jmx.remote.x.password.file", "PATH\\password.properties");
 env.put("jmx.remote.x.access.file", "PATH\\access.properties");
 JMXConnectorServer cs =
  JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);

 
MyApp2側の実装

 HashMap env = new HashMap();
 String[] credentials = new String[] { "admin" , "adminpasswd" }; 
 env.put("jmx.remote.credentials", credentials); 

 
「"admin" , "adminpasswd"」は、password.propertiesに記載されているアカウント情報になります。

 access.propertiesの内容
 guest   readonly
 admin   readwrite
 
 password.propertiesの内容
 guest  guestpasswd
 admin  adminpasswd

jconsoleで接続する際も、IDとパスワードが必要になります。
 

JSSE で使用するキーストアの作成

SSLを用いた通信に関しても試してみます。概念は、「3.2 SSL環境の構築手順」を参考に概念を理解してみました。
キーストア、トラストストアを利用したJMXアクセスを実現してみます。
 
キーストアを作成する為に、以下のコマンドを実行します。

 keytool -genkeypair -dname "cn=Mark Jones, ou=JavaSoft, o=Sun, c=US" -alias duke -keyalg RSA -validity 7 -keystore PATH\keystore

 
「keytool -list -v -keystore PATH\keystore」を実行して、生成したファイルの中身を確認します。

 キーストアのタイプ: JKS
 キーストアのプロバイダ: SUN
 
 キーストアには 1 エントリが含まれます。
 
 別名: duke
 作成日: 2011/03/22
 エントリタイプ: PrivateKeyEntry
 証明連鎖の長さ: 1
 証明書[1]:
 所有者: CN=Mark Jones, OU=JavaSoft, O=Sun, C=US
 発行者: CN=Mark Jones, OU=JavaSoft, O=Sun, C=US
 シリアル番号: 4d88319f
 有効期間の開始日: Tue Mar 22 14:20:31 JST 2011 終了日: Tue Mar 29 14:20:31 JST 2011
 証明書のフィンガープリント:
         MD5:  90:57:3E:53:55:DC:00:A1:47:********************************
         SHA1: 3A:CA:B0:BF:6C:C9:2D:44:FB:********************************
         署名アルゴリズム名: SHA1withRSA
         バージョン: 3

 
証明書を抜き出します。

keytool -export -alias duke -keystore PATH\keystore -rfc -file duke.cer

 

$cat duke.cer
 -----BEGIN CERTIFICATE-----
 MIIB/TCCAWagAwIBAgIETYgxnzANBgkqhkiG9w0BAQUFADBDMQswCQ**********************
 ChMDU3VuMREwDwYDVQQLEwhKYXZhU29mdDETMBEGA1UEAxMKTWFyay**********************
 NTIwMzFaFw0xMTAzMjkwNTIwMzFaMEMxCzAJBgNVBAYTAlVTMQwwCg**********************
 BAsTCEphdmFTb2Z0MRMwEQYDVQQDEwpNYXJrIEpvbmVzMIGfMA0GCS**********************
 iQKBgQCovlJ5+OvljiNvUuFo5v2CPxac0HP3gjUOv69h1SPxKrI0p3**********************
 Uj32NWr7GC60ZkUejduIDVoaShlr1ThhKsKJuNlHUjGcI2rTz59BKR**********************
 mwlVExvOjolt7g7JJabUmVGdxwIDAQABMA0GCSqGSIb3DQEBBQUAA4**********************
 absWJKvco1hUAJG0qlcvrih4MAMnhd6M4O8RXBINQtI7ER/6ilygIh**********************
 pALI4QESdL4fuwMpGvsviMtcbTYUabOrG+Tef0WCq1+aaAMGAuQvXP**********************
 -----END CERTIFICATE-----

 
証明書を新しいトラストストアにインポートします。

 keytool -import -alias dukecert -file duke.cer -keystore PATH\truststore

 
「keytool -list -v -keystore PATH\truststore」を実行して、トラストストアを確認します。

 キーストアのタイプ: JKS
 キーストアのプロバイダ: SUN
 
 キーストアには 1 エントリが含まれます。

 別名: dukecert
 作成日: 2011/03/22
 エントリのタイプ: trustedCertEntry
 
 所有者: CN=Mark Jones, OU=JavaSoft, O=Sun, C=US
 発行者: CN=Mark Jones, OU=JavaSoft, O=Sun, C=US
 シリアル番号: 4d88319f
 有効期間の開始日: Tue Mar 22 14:20:31 JST 2011 終了日: Tue Mar 29 14:20:31 JST 2011
 証明書のフィンガープリント:
         MD5:  90:57:3E:53:55:DC:00:A1:********************************
         SHA1: 3A:CA:B0:BF:6C:C9:2D:44:********************************
         署名アルゴリズム名: SHA1withRSA
         バージョン: 3

生成したキーストアとトラストストアを利用して、JMXにアクセスしてみます。
 
MyApp側の実装

 HashMap<String,Object> env = new HashMap<String,Object>();
 SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory();
 SslRMIServerSocketFactory ssf = new SslRMIServerSocketFactory();
 env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf);
 env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf);
 env.put("jmx.remote.x.password.file", "PATH\\password.properties");
 env.put("jmx.remote.x.access.file", "PATH\\access.properties");
 JMXConnectorServer cs =
  JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);

起動する際に、VM引数に、「-Djavax.net.ssl.keyStore=PATH\keystore -Djavax.net.ssl.keyStorePassword=password」を指定する。
 
jconsole でアクセスする場合は、下記の様にオプションを指定し、起動する。

 jconsole -J-Djavax.net.ssl.trustStore=D:\usr\home\dev1\al\build\truststore -J-Djavax.net.ssl.trustStorePassword=trustword

 
MyApp2を実行する際は、VM引数に、「-Djavax.net.ssl.trustStore=PATH\truststore -Djavax.net.ssl.trustStorePassword=trustword」を指定する。
実行すると下記のような感じで表示することができました。

 url=service:jmx:rmi:///jndi/rmi://:3000/jmxrmi
 connector=javax.management.remote.rmi.RMIConnector: jmxServiceURL=service:jmx:rmi:///jndi/rmi://:3000/jmxrmi
 connection=javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection@77158a
 memoryMXBean=MXBeanProxy(javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection@77158a[java.lang:type=Memory])
 init = 0(0K) used = 4219152(4120K) committed = 5177344(5056K) max = 66650112(65088K)

 

Attach API実行時に、ローカルで実行されているJavaアプリケーションをMBeanServerに登録する

Attach APIに関しては、ITproさんの「第10回 オンデマンドアタッチを実現するAttach API」を参考に
実行してみましたが、うまくいきませんでした。

その為、「JMXにアクセスできるようにServerとClientを実装してみる」を試してみて、どこか変更の余地があるか
調べてみました。
 
サンプルの元(AttachAgent.java

 public static final String SERVICE_URL
  = "service:jmx:rmi:///jndi/rmi://localhost/jmx";
 // MXBean を登録してある MBeanServer を取得
 MBeanServer server = ManagementFactory.getPlatformMBeanServer();
 
 // JMX Remote を使用したリモート接続の設定
 JMXServiceURL url = new JMXServiceURL(SERVICE_URL);
 JMXConnectorServer connector
  = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server);
 
  // コネクタの開始
  connector.start();

 
「connector.start()」処理でどうしてもExceptionが発生してしまうので、下記のとおり変更してみました。

サンプルの変更後(AttachAgent.java

 public static final String SERVICE_URL
  = "service:jmx:rmi:///jndi/rmi://:3000/jmxrmi";
 
 System.out.println("Create RMI registry on port 3000");
 LocateRegistry.createRegistry(3000);
 // MXBean を登録してある MBeanServer を取得
 MBeanServer server = ManagementFactory.getPlatformMBeanServer();
 
 // JMX Remote を使用したリモート接続の設定
 JMXServiceURL url = new JMXServiceURL(SERVICE_URL);
 JMXConnectorServer connector
  = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server);
 
  // コネクタの開始
  connector.start();

 
上記のようなソースにし、実行してみると下記のような感じでうまく登録できたようでした。

 java AttachSample
 5968: sun.tools.jconsole.JConsole
 
 java AttachSample 5968
 init = 0(0K) used = 7767776(7585K) committed = 8736768(8532K) max = 66650112(65088K)

java AttachSample」でローカルで実行しているJavaプロセスの一覧を表示します。
その後、「java AttachSample 5968」で、JConsoleにJMX経由でアクセスし、MemoryMXBeanの値を取得しました。*3
 

さくらVPSで実行しているCassandraで、Attach API経由で、MXBeanが確認できるか試してみる

 java AttachSample
 PID   VM
 766: org.apache.cassandra.thrift.CassandraDaemon
 
 java AttachSample 766
 init = 536870912(524288K) used = 21404216(20902K) committed = 510066688(498112K) max = 510066688(498112K)

上記のような感じで、Cassandra内のメモリ情報をMemoryMXBeanを利用して、使用量を確認することができました。


*1:記事のコードだと一部うまくいきませんでした。

*2:JMX リモート API を使用したアウトオブボックスの管理の模倣」を参考

*3:実行時の引数などは、省略してます