2014年12月4日木曜日

MBAのVagrantでubuntuを起動する

Windows7にVirtual Boxをインストールしたので、vagrantもインストールしたのですが、低スペックだったせいかVMを起動できませんでした。。

その後、MacBookAirを購入したので、Virtual Boxとvagrantをインストールし、リベンジしてみました。

ということで、vagrantのbox追加からdestroyまでをまとめていこうと思います!

まずは、boxの追加をします。boxは、vagrant cloudで好きなものや用途にあったものを選びます。

今回は、ubuntu 14.0.4を選んでみました。
boxを選んだら、ターミナルでboxを追加します。

boxの追加はvagrantのboxコマンドで行います。
まずは追加なので、サブコマンドにaddを指定し、引数にbox名とボックスのURLを入力します。

vagrant box add box名 ダウンロード元URL

上記の形式に沿って、実行したのが下記のコマンドになります!

$ vagrant box add ubuntu/trusty32 https://vagrantcloud.com/ubuntu/boxes/trusty32
==> box: Loading metadata for box 'https://vagrantcloud.com/ubuntu/boxes/trusty32'
==> box: Adding box 'ubuntu/trusty32' (v14.04) for provider: virtualbox
    box: Downloading: https://vagrantcloud.com/ubuntu/boxes/trusty32/versions/14.04/providers/virtualbox.box 
==> box: Box download is resuming from prior download progress 
==> box: Successfully added box 'ubuntu/trusty32' (v14.04) for 'virtualbox'! 

これでboxを追加できました!追加したboxは、listサブコマンドで確認できます。

$ vagrant box list 
ubuntu/trusty32 (virtualbox, 14.04) 

追加したときに指定した、box名があれば追加完了です!追加できていることを、確認できましたので、実際に起動してみようと思います。

VMを起動するときは、vagrant upコマンドを実行します。

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider... 
==> default: Importing base box 'ubuntu/trusty32'... 
==> default: Matching MAC address for NAT networking... 
==> default: Checking if box 'ubuntu/trusty32' is up to date... 
==> default: Setting the name of the VM: virtual-env_default_1417616732058_47717 
==> default: Clearing any previously set forwarded ports... 
==> default: Clearing any previously set network interfaces... 
==> default: Preparing network interfaces based on configuration... 
    default: Adapter 1: nat 
==> default: Forwarding ports... default: 22 => 2222 (adapter 1) 
==> default: Booting VM... 
==> default: Waiting for machine to boot. This may take a few minutes... 
    default: SSH address: 127.0.0.1:2222 
    default: SSH username: vagrant 
    default: SSH auth method: private key 
    default: Warning: Connection timeout. Retrying... 
    default: Warning: Remote connection disconnect. Retrying... 
==> default: Machine booted and ready! 
==> default: Checking for guest additions in VM... 
==> default: Mounting shared folders... 
    default: /vagrant => /Users/Development/virtual-env

起動時に設定情報が表示され、エラーもなくコマンドが終われば起動完了です。

問題なく起動できたら、vagrantのsshコマンドで起動したVMに接続してみます。

$ vagrant ssh 
Welcome to Ubuntu 14.04.1 LTS (GNU/Linux 3.13.0-40-generic i686)
   * Documentation: https://help.ubuntu.com/

   System information as of Wed Dec 3 14:25:52 UTC 2014 

   System load: 0.83 Processes: 89 
   Usage of /:  2.6% of 39.34GB Users logged in: 0
   Memory usage: 10% IP address for eth0: 10.0.2.15 
   Swap usage:    0% 

   Graph this data and manage this system at: 
       https://landscape.canonical.com/ 

   Get cloud support with Ubuntu Advantage Cloud Guest:       
       http://www.ubuntu.com/business/services/cloud

0 packages can be updated. 
0 updates are security updates. 

vagrant@vagrant-ubuntu-trusty-32:~$ 

接続できるかドキドキしましたが、無事に接続できることが確認できました!

作業が終わり切断したいときは、exitコマンドを使います。

vagrant@vagrant-ubuntu-trusty-32:~$ exit 
logout
Connection to 127.0.0.1 closed. 

切断後、VMを停止したいときは、haltコマンドで停止することができます。

$ vagrant halt 
==> default: Attempting graceful shutdown of VM... 

追加したVMがいらなくなったときは、destroyコマンドで破棄できます。

$ vagrant destroy 
   default: Are you sure you want to destroy the 'default' VM? [y/N] y
==> default: Destroying VM and associated drives...

作業自体は、難しくないのでどうなっても良い環境が欲しいときは良いと思います。

2014年12月3日水曜日

Symfony1.4のDoctrineで大量のデータ操作をした時に Allowed memory size...のエラーになる

Symfony1.4のDoctrineで、1万件くらいのデータを取り出してforeachで1件ずつ更新しようとしたところ、Allowed memory size..のエラーがでてしまいました。

PHP Fatal error:  Allowed memory size of 536870912 bytes exhausted (tried to allocate 32 bytes)

このエラーが出た時は、php.iniのmemory_limitを変更すれば、防げるようになるのですが、php.iniを変更できなかったり、変更したくないことも多いと思います。。

今回は、php.iniを変更したくなかったので、設定以外で対応したいと思っていたところ、Doctrineにはfree()というものがあり、オブジェクトを解放できることがわかりました。

free()は、Doctrine_RecordとDoctrine_Query、Doctrine_Collectionで使うことができるみたいです。

試しにテーブルから5000件抽出し、ループでupdated_atカラムを更新するプログラムを実行してみました。

// Usersテーブルから5000件のデータを抽出
$q = Doctrine_Query::create()
     ->from('User u')
     ->limit(5000)
     ->orderBy('u.id ASC')
     ->execute();

foreach ($q as $k => $val) {
      $val->updated_at = date("Y-m-d H:i:s");
      $val->save();
      if ($k % 500 == 0){
            printf("%d : %dKB\n", $k, (memory_get_usage(true) / 1024));
      }
      $val->free();
}
$q->free();
printf("End : %dKB\n", $k, (memory_get_usage(true) / 1024));


効果があるのかを判定するために、まずは$val->free()をコメントアウトして実行してみました。

0        : 94976KB
500   : 99072KB
1000 : 102912KB
1500 : 106752KB
2000 : 111616KB
2500 : 115712KB
3000 : 119552KB
3500 : 123392KB
4000 : 127232KB
4500 : 131840KB
End    : 137728KB

実行結果からもわかるように、メモリがどんどん増えていきます。今回はこれを増えないようにしたいので、$val->free()を有効にして実行してみます。

0       : 94976KB
500   : 95488KB
1000 : 95744KB
1500 : 96000KB
2000 : 97024KB
2500 : 97024KB
3000 : 97024KB
3500 : 97024KB
4000 : 97024KB
4500 : 97536KB
End    : 99584KB

多少は増えますが、なにもしないときよりも38144KBのメモリを抑えることができましたので、大量にデータを扱うときは対策をするべきだなと思いました。

また、テーブルを結合している場合は、引数にtrueを渡してfree(true)と指定することで、リレーションのオブジェクトもすべて解放することができます。

macOSでminikubeをインストールしようとしたら書き込みエラーになった

ローカル環境でKubernetesを使えるようにしようと環境構築中にエラーが 下記が今回のエラーで書き込みできない感じのメッセージが出ています。  $ brew install minikube Updating Homebrew... Error: The following ...