Hatena::ブログ(Diary)

130単位

2011-03-31

2010年に読んだ本のお気に入り10冊

年度末ということもあり、3ヶ月ずれていますが2010年分の読書まとめです。

記録上では1年で137冊読んでいました(漫画含む)。

一般書籍×6

433403425X
お金は銀行に預けるな 金融リテラシーの基本と実践 (光文社新書)

この本がきっかけで、普通預金しか知らなかった状態から資産運用を始められました。あって損はない知識ですし、実践して経験を積み重ねるのがいいと思います。


4847041941
ナインティナインのオールナイトニッ本 (vol.1)

懐かしさがこみ上げまくりです。vol.3にも期待です。


4153200115
小さなチーム、大きな仕事―37シグナルズ成功の法則 (ハヤカワ新書juice)

モダンな仕事術/経営術のエッセンスが詰まっています。


4798026182
本気で稼ぐための「アフィリエイト」の真実とノウハウ

稼ぐ近道は存在しないことを示した上で、どうすればよいか書かれています。


4198629668
拝金

ノンフィクション風味で楽しめます。多岐に渡るプロモーション手法も印象的でした。


4839934444
iPhoneとツイッターで会社は儲かる (マイコミ新書)

PS3のTV会議に憧れます。共有の大切さが再確認できます。


技術書×3

4774143073
[Web開発者のための]大規模サービス技術入門 ―データ構造、メモリ、OS、DB、サーバ/インフラ (WEB+DB PRESS plusシリーズ)

ノウハウの詰まったインターン講義が疑似体験できます。


4798027456
Pocket詳解 CakePHP辞典

2010年、ページを開いた回数が最も多かった本です。CakePHP開発なら必携かと。


4774144371
パーフェクトPHP (PERFECT SERIES 3)

PHP開発なら必読。


漫画×1

406372171X
少女ファイト(1) (イブニングKCDX)

個性的な絵と、複数のキャラの立ち方が秀逸に感じます。


2010年の読書記録

1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月

2011年は読書は停滞気味なのですが、月10冊ペースで読めるといいかなと思います。技術の学習も怠らないようにしたいです。


関連記事


2011-03-30

2月分の読書記録

えー1冊しか記録していないのですが、月1回の定例エントリなので更新しておきます。なんかすいません。

きのこ本とか小悪魔サーバ本とかは読みかけです。12月のWEB+DBも今ちょうどjQueryやっているので読んでみたいところです。

2月分読書データ

期間 : 2011年02月
読了数 : 1 冊
ONE PIECE 61 (ジャンプコミックス)
尾田 栄一郎 / 集英社 (2011-02-04)
★★★★☆ 読了日:2011年2月6日
再会からの幕開けがすがすがしい。カバーイラストが粋


メディアマーカー

1月分の読書記録 - 130単位 (一ヶ月前)

2月分の読書記録 - 130単位 (一年前)

2011-03-29

CakePHP 日付別パーティショニングするビヘイビア

MySQL 日付別パーティショニングの運用 - 130単位

前回MySQLのパーティショニングを簡単にまとめてみました。実験はCakePHPアプリでしていて、ついでにつくったビヘイビアを晒してみます。GitHubにもあげてます。

no title

ビヘイビア

app/models/behaviors/以下にdate_partitionable.phpとして保存します。中身はSQLをつくって実行しているだけの単純なものです。

<?php
class DatePartitionableBehavior extends ModelBehavior {
    public function createPartition(&$Model, $field, $date) {
        $ts = strtotime($date);
        if ($ts === false) { return false; }

        $partition_name = $this->_getPartitionName($ts);
        $partition_date = $this->_getPartitionDate($ts);

        $sql = "ALTER TABLE {$Model->table} PARTITION BY RANGE (TO_DAYS({$field})) ";
        $sql .= "(PARTITION {$partition_name} VALUES LESS THAN (TO_DAYS('{$partition_date}')) COMMENT = '{$partition_date}')";

        return $Model->query($sql);
    }

    public function removePartition(&$Model) {
        $sql = "ALTER TABLE {$Model->table} REMOVE PARTITIONING";

        return $Model->query($sql);
    }

    public function addPartition(&$Model, $date) {
        $ts = strtotime($date);
        if ($ts === false) { return false; }

        $partition_name = $this->_getPartitionName($ts);
        $partition_date = $this->_getPartitionDate($ts);

        $sql = "ALTER TABLE {$Model->table} ADD PARTITION ";
        $sql .= "(PARTITION {$partition_name} VALUES LESS THAN (TO_DAYS('{$partition_date}')) COMMENT = '{$partition_date}')";

        return $Model->query($sql);
    }

    public function dropPartition(&$Model, $date) {
        $ts = strtotime($date);
        if ($ts === false) { return false; }

        $partition_name = $this->_getPartitionName($ts);

        $sql = "ALTER TABLE {$Model->table} DROP PARTITION {$partition_name}";

        return $Model->query($sql);
    }

    private function _getPartitionName($ts) {
        return 'p' . date('Ymd', $ts);
    }

    private function _getPartitionDate($ts) {
        return date('Y-m-d', $ts + 86400) . ' 00:00:00';
    }
}

Cakeシェル

Cakeシェルのサンプルです。app/vendors/shells/以下にpartition.phpとして保存します。usesプロパティの先頭要素のモデルがパーティショニングの対象になります。main()以外のメソッドをつくることで、Cakeタスクの代わりになります。引数でモデルを指定してもよかったのですが、面倒なのでやめました。

<?php
class PartitionShell extends Shell {
    public $uses = array('GameHistory'); //input partitionable target model name on first.
    public $tasks = array();

    public function startup() {
        $this->{$this->modelClass}->Behaviors->attach('DatePartitionable');
    }

    public function create() {
        $count = (isset($this->args[0])) ? intval($this->args[0]) : 1;

        $this->{$this->modelClass}->createPartition('created', date('Ymd'));
        for ($i = 1; $i < $count; $i++) {
            $this->{$this->modelClass}->addPartition(date('Ymd', strtotime('+' . $i . ' days')));
        }
    }

    public function remove() {
        $this->{$this->modelClass}->removePartition();
    }

    public function add() {
        if (!isset($this->args[0])) {
            $this->err("[ERROR] require date parameter. ex: 'add 20110101'");
            return;
        }
        $this->{$this->modelClass}->addPartition($this->args[0]);
    }

    public function drop() {
        if (!isset($this->args[0])) {
            $this->err("[ERROR] require date parameter. ex: 'drop 20110101'");
            return;
        }
        $this->{$this->modelClass}->dropPartition($this->args[0]);
    }
}

Cakeシェル実行例

cake/console/cake partition create
#-> ALTER TABLE game_histories PARTITION BY RANGE (TO_DAYS(created)) (PARTITION p20110329 VALUES LESS THAN (TO_DAYS('2011-03-30 00:00:00')) COMMENT = '2011-03-30 00:00:00')
cake/console/cake partition add 20110330
#-> ALTER TABLE game_histories ADD PARTITION (PARTITION p20110330 VALUES LESS THAN (TO_DAYS('2011-03-31 00:00:00')) COMMENT = '2011-03-31 00:00:00')
cake/console/cake partition drop 20110330
#-> ALTER TABLE game_histories DROP PARTITION p20110330
cake/console/cake partition remove
#-> ALTER TABLE game_histories REMOVE PARTITIONING

直打ちで試してみて問題なさそうであれば、cronジョブに登録して自動化するといいんじゃないかと思います。不具合などありましたらご報告いたけますと助かります!


4798027456
Pocket詳解 CakePHP辞典

4774142948
エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド

関連記事

2011-03-27

MySQL 日付別パーティショニングの運用

MySQL :: MySQL 5.1 リファレンスマニュアル :: 15 パーティショニング
http://dev.mysql.com/doc/refman/5.1/ja/partitioning.html

実験的にやってみただけでノウハウとして固まってはいないのですが、現状の知識をまとめてみたいと思います。

前提

  • MySQL 5.1以降
    • 検証した環境は5.1.47
  • 日付ごとにパーティショニング
  • カラムは一意な"id"と作成日付の"created"があるとする

準備

  • idとcreatedを複合でプライマリキーにする
    • パーティショニングの条件はプライマリキーに含める必要がある
    • idがAUTO_INCREMENTであればPRIMARY KEY (id, created)の順のみ
  • createdをTO_DAYS()してパーティショニングする
    • 大枠と個別のパーティションの両方でTO_DAYS()する
    • UNIX_TIMESTAMP()とどちらがいいのかは未検証
    • 5.5からはDATETIME型のままできるとのこと
  • TO_DAYS()した値は認識しづらいので、COMMENTで年月日がわかるようにしておく
  • 運用開始時の取りうる日付から数日間先まで追加しておく
    • 週単位/月単位/年単位のどれが適しているかは未検証
  • バッファとしての VALUES LESS THAN MAXVALUE は使わない
    • 新たなパーティションの追加ができなくなるため
    • REORGANIZE PARTITIONで再配置できるが時間がかかる
SQL
-- 大枠追加
ALTER TABLE table PARTITION BY RANGE (TO_DAYS(created))
	(PARTITION p20110327 VALUES LESS THAN (TO_DAYS('2011-03-28 00:00:00')) COMMENT = '2011-03-28 00:00:00');
-- 値追加
ALTER TABLE table PARTITION ADD PARTITION
	(PARTITION p20110328 VALUES LESS THAN (TO_DAYS('2011-03-29 00:00:00')) COMMENT = '2011-03-29 00:00:00');
スキーマ
-- SHOW CREATE TABLEの結果
CREATE TABLE `game_histories` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(10) unsigned NOT NULL,
  `score` int(10) unsigned NOT NULL,
  `created` datetime NOT NULL,
  PRIMARY KEY (`id`,`created`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (TO_DAYS(created))
 PARTITION p20110327 VALUES LESS THAN (734589) COMMENT = '2011-03-28 00:00:00' ENGINE = InnoDB,
 PARTITION p20110328 VALUES LESS THAN (734590) COMMENT = '2011-03-29 00:00:00' ENGINE = InnoDB,
 PARTITION p20110329 VALUES LESS THAN (734591) COMMENT = '2011-03-30 00:00:00' ENGINE = InnoDB,
 PARTITION p20110330 VALUES LESS THAN (734592) COMMENT = '2011-03-31 00:00:00' ENGINE = InnoDB,
 PARTITION p20110331 VALUES LESS THAN (734593) COMMENT = '2011-04-01 00:00:00' ENGINE = InnoDB */

運用

SQL
-- 値削除
ALTER TABLE table DROP PARTITION p20110327;
-- 大枠削除
ALTER TABLE table REMOVE PPARTITIONING;

-- データ分布確認
SELECT table_schema, table_name, partition_name, partition_ordinal_position, table_rows FROM information_schema.partitions WHERE table_name = 'game_histories';
-- 刈り込み(pruning)確認
EXPLAIN PARTITIONS SELECT * FROM game_histories WHERE created < '2011-03-28 00:00:00';

参考リンク

以下の記事のおかげでできました。ありがとうございます!


4774142948
エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド

4873114268
実践ハイパフォーマンスMySQL 第2版

2011-03-26

Redmine チケット一覧 ステータスで色分け表示

対応中や対応済のチケットを認識しやすくするため、色分け表示します。対象ステータスNoのclassを指定してスタイルを記述します。

こちらのテーマに合わせて編集したものですが、通常テーマでも使えます。優先度で赤と青が使われているので、それ以外で。

/* yellow style */ 
tr.odd.status-2 { background: #ffe; }
tr.even.status-2 { background: #fffff2; }
tr.odd.status-2 td, tr.even.status-2 td { border-color: #ffc; }
tr.status-2 td.status { color: #990; }
/* green style */
tr.odd.status-3 { background: #efe; }
tr.even.status-3 { background: #f2fff2; }
tr.odd.status-3 td, tr.even.status-3 td { border-color: #cfc; }
tr.status-3 td.status { color: #090; }
/* purple style */
tr.odd.status-4 { background: #fef; }
tr.even.status-4 { background: #fff2ff; }
tr.odd.status-4 td, tr.even.status-4 td { border-color: #fcf; }
tr.status-4 td.status { color: #909; }

対応済になって色が変わったりするのは、多少なりとも達成感アップにつながるんじゃないかと思います。

関連リンク

日本語環境で読みやすいRedmine用テーマ「farend basic」公開 | Redmine.JP Blog

2011-03-24

Rails3 MySQL/jQueryを利用するアプリの作成手順

Rails3はSQLite3とPrototypeデフォルトになっていますが、業務などで実際に扱う際はMySQLjQueryを利用することが多いと思います。そこで個人的なアプリ作成手順が固まってきたので、一旦まとめてみます。調査/検証目的のアプリの想定で、テストの生成もしないようにしてます。

環境

アプリ作成

rails new sample -JT -d mysql

Gemインストール

cd sample
  • Gemfile編集
gem 'mysql2', '< 0.3' #0.3以上はRails3.1以上でないと動かない
group :development do #開発時しか必要でないため
  gem 'jquery-rails'
end
bundle install

MySQL利用

  • config/database.yml編集
development:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: sample_development
  pool: 5
  username: root
  password:
  host: localhost
  socket: /var/mysql/mysql.sock #socket追加
    • Ubuntuは/var/run/mysqld/mysqld.sock
    • test用の設定にもsocket追記、不要ならまるごと消す
  • 開発用DB作成
mysql -u root -p -e 'CREATE DATABASE sample_development'
  • 【追記】rakeコマンドでもできます(test用DBもつくられる)
rake db:create RAILS_ENV=development

jQuery利用

rails g jquery:install
  • 「SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)」とエラーになる場合
    • config/application.rbに以下を記述
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
  • 【追記】config/application.rb 設定パラメータ編集
config.action_view.javascript_expansions[:defaults] = %w(jquery jquery_ujs) #v1.0.1以上
config.action_view.javascript_expansions[:defaults] = %w(jquery rails) #v1.0.1未満
    • こうすると<%= javascript_include_tag :defaults %>がそのまま使える
  • 【非推奨】app/views/layouts/application.html.erb編集
  <%= javascript_include_tag 'jquery' %>
  <%= javascript_include_tag 'rails' %>
    • 「<%= javascript_include_tag :defaults %>」は消す

テスト生成無効化

  • config/environments/development.rb編集
Sample::Application.configure do
  config.generators do |g|
    g.test_framework false
  end
  #...
end

簡易デバッグライブラリ

  • config/environments/development.rb編集
require 'pp'
    • p を使うよりも少しわかりやすい
    • pp obj とかするとWEBrickのログで見られる
  • 【追記】タイプ数は多いですが導入不要なので logger.debug を使うのが良さげ
logger.debug object.inspect #オブジェクトを読みやすく表示
logger.debug object.to_yaml #YAML形式で表示

Scaffoldマイグレーション

rails g scaffold user name:string
rake db:migrate

アプリ起動

rails s

参考リンク


4774146633
Ruby on Rails 3 アプリケーションプログラミング

4048687158
メタプログラミングRuby

関連記事

2011-03-07

AWS EC2 Webサーバーデプロイ用シェルスクリプト

EC2のWebコンソール画面から地道にデプロイするのもしんどくなってきたので、シェルコマンドで自動化を試みてみました。ここでのデプロイという言葉はWebサーバーの資源入れ替えを指してます。

前提

シェルスクリプト

#!/bin/sh

if [ $# -lt 2 ]; then
	echo "Usage: sh deploy.sh (var file) (key file)"
	exit 1
elif [ ! -f "$HOME/aws/vars/$1" ]; then
	echo "var file not found."
	exit 1
elif [ ! -f "$HOME/aws/keys/$2" ]; then
	echo "key file not found."
	exit 1
fi

source $HOME/aws/vars/$1

KEY=$HOME/aws/keys/$2
DESC_CMD="ec2-describe-instances -F group-id=production-web"
INIT_CMD="/usr/bin/wget -q -O- http://169.254.169.254/latest/user-data | /usr/bin/base64 -d -i | /usr/bin/bzip2 -dcq | /bin/sh"
LB="production-lb"

for i in `$DESC_CMD | grep INSTANCE | cut -f2,4 | sed 's/\t/,/g'`
do
	INSTANCE=`echo $i | cut -f1 -d ','`
	HOST=`echo $i | cut -f2 -d ','`
	echo "***Deregistering $INSTANCE"
	elb-deregister-instances-from-lb $LB --instances $INSTANCE
	echo "***Deploying $INSTANCE"
	ssh -i $KEY root@$HOST $INIT_CMD
	echo "***Registering $INSTANCE"
	elb-register-instances-with-lb $LB --instances $INSTANCE
done

つかいかた

export EC2_CERT="$HOME/aws/keys/app/cert-XXXXX.pem"
export EC2_PRIVATE_KEY="$HOME/aws/keys/app/pk-XXXXX.pem"
export EC2_URL="https://ec2.ap-northeast-1.amazonaws.com"
export EC2_REGION="ap-northeast-1"

上記を環境変数定義ファイルに記述して

sh deploy.sh 環境変数定義ファイル SSH秘密鍵ファイル

せつめい

メリット

  • コマンド一発
  • 無停止デプロイ
  • オートスケーリングと共存可能
  • 可変なインスタンスに対応
  • 同じ仕組みの複数の本番環境に対応

デメリット


かなり偏った前提条件と環境ではあると思いますが、とりあえず効率化することができました。とはいえ特にWebサーバーが多いとデメリットも無視できないので、並列処理ができるらしいCapistranoを素直に利用したほうがよさそうな気がします。


4774142840
よくわかるAmazonEC2/S3入門 ―AmazonWebServicesクラウド活用と実践 (Software Design plusシリーズ)

4844329804
Amazon Web Services ガイドブック クラウドでWebサービスを作ろう!

2011-03-05

Amazon Linux Redmine1.1.1/Passenger3環境構築

AWS Free Usage Tier
http://aws.amazon.com/jp/free/

日本リージョンがリリースされたばかりのAWSで、Amazon Linuxを使ってRedmineをセットアップしてみました。

環境

$ head -n 1 /usr/share/doc/amzn-ami/image-release-notes
Changes in Amazon Linux AMI Beta2 (v 2010.11):

パッケージはRedHat系のようにyumで管理されています。リポジトリがamznとなっており、ソフトによってCentOSと比べて新しめのバージョンが利用できます。

パッケージインストール

#アップデート
sudo yum -y update
#(たぶん)必要なもの
sudo yum -y install gcc
sudo yum -y install kernel-devel  
#MySQL
sudo yum -y install mysql-server
#MySQL gem用
sudo yum -y install mysql-devel
sudo yum -y install ruby-devel
#Apache
sudo yum -y install httpd
#Passenger用
sudo yum -y install gcc-c++ curl-devel openssl-devel zlib-devel httpd-devel apr-devel 

MySQL設定

  • なんとなくmy-small.cnfをベースにした
sudo cp /etc/my.cnf /etc/my.cnf.bak
sudo cp /usr/share/mysql/my-small.cnf /etc/my.cnf
  • my.cnf編集
    • [mysqld]と[mysql]に「default-character-set = utf8」追記
sudo /etc/init.d/mysqld start
sudo /sbin/chkconfig mysqld on
mysql -u root
CREATE DATABASE redmine
GRANT ALL ON redmine.* TO (user)@"localhost" INDENTIFIED BY '(password)';
  • 「mysql_secure_installation」を実行しておくとよい

Ruby

$ ruby -v
ruby 1.8.7 (2010-08-16 patchlevel 302) [i386-linux]

RubyGems

wget http://rubyforge.org/frs/download.php/73882/rubygems-1.4.2.tgz
tar xzf rubyems-1.4.2.tgz
sudo ruby rubygems-1.4.2/setup.rb
sudo gem install rails -v=2.3.5
sudo gem install rack -v=1.0.1
sudo gem install i18n -v=0.4.2
sudo gem install mysql
  • yumだとバージョン1.3.5

Redmine

wget http://rubyforge.org/frs/download.php/74128/redmine-1.1.1.tar.gz
tar xzf redmine-1.1.1.tar.gz
mv redmine-1.1.1 /var/www/html/redmine
cd /var/www/html/redmine/
cp config/database.yml.example config/database.yml
vim config/database.yml
  • DB設定ファイル編集
production:
  adapter: mysql
  database: redmine
  host: localhost
  username: (user)
  password: (password)
  encoding: utf8
  socket: /var/lib/mysql/mysql.sock
rake config/initializers/session_store.rb
rake db:migrate RAILS_ENV="production"
rake redmine:load_default_data RAILS_ENV="production"

Apache/Passenger

sudo passenger-install-apache2-module
  • Apache設定ファイル編集
   LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-3.0.4/ext/apache2/mod_passenger.so
   PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-3.0.4
   PassengerRuby /usr/bin/ruby

   <VirtualHost *:80>
      ServerName www.yourhost.com
      DocumentRoot /var/www/html/redmine/public
      <Directory /var/www/html/redmine/public>
         AllowOverride all
         Options -MultiViews
      </Directory>
   </VirtualHost>
sudo /etc/init.d/httpd start
sudo /sbin/chchkconfig httpd on
mysql -u root
おまけ

Amazon LinuxApacheデフォルトページ

f:id:deeeki:20110324072834j:image

遭遇したエラー

gem install mysql

ERROR: Error installing mysql:

ERROR: Failed to build gem native extension.

/usr/bin/ruby extconf.rb

mkmf.rb can't find header files for ruby at /usr/lib/ruby/ruby.h

  • ruby-develが入ってなかったため
  • 参考:no title
  • sudo yum install ruby-devel して解決
rake db:migrate時

rake aborted!

uninitialized constant ActiveSupport::Dependencies::Mutex

  • RubyGemsが最新の1.6.1だったため
  • システム要件に以下のように書いてある

RubyGems 1.3.1 or higher is required (Rails 2.3.5 will fail with RubyGems 1.5.0 and later, stick to previous versions of RubyGems)

RedmineInstall - Redmine
  • Gemsのバージョンを1.4.2にして解決

関連リンク


4844329804
Amazon Web Services ガイドブック クラウドでWebサービスを作ろう!

4798027057
入門Redmine 第2版 Linux/Windows対応


【関連記事】
Ubuntu 10.10 RVM/Ruby1.8/Rails2/Passenger2環境構築 - 130単位

2011-03-02

ブロガー名刺をつくってみる

ブロガー名刺、送料込みで1000円じゃすと! - 川柳をこよなく愛する明石のタコ
http://blog.goo.ne.jp/batacchi/e/f81808a384944befed668cab7a8c3993

ふと思い立って、プライベート用の名刺をつくってみることにしました。

前川企画印刷さんのブロガー名刺、特徴は以下のような感じです。

  • 白黒は100枚1000円
  • カラーは100枚1300円
  • 両面カラーは100枚1800円
  • 料金は送料込み
  • 申し込みの際にトラックバック送信が必要
  • デザインはデザイナーさんが(ブログをみて)提案してくれる
  • 校正は何度でもok
  • 紙質はしっかりしてるらしい
  • 箱入りで納品
  • 最短で注文から3日で届くらしい
  • 商品到着後に銀行振込で後払い

そんなわけで事前トラックバックのため、つくっていただくのはこれからになります。できあがったら追記か別記事にて紹介してみたいと思います。

ちなみに下記の記事も読んでみて、最安値100枚998円と同じ値段で品質は上っぽかったので、前川企画印刷さんに決めました。

関連リンク

以下は知るきっかけとなったIDEA*IDEAの記事。