tag:blogger.com,1999:blog-11237439299189819502024-02-09T04:22:56.502+09:00blog.hori-uchi.comhoriuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.comBlogger401125tag:blogger.com,1999:blog-1123743929918981950.post-83892544406405657352010-10-13T15:57:00.006+09:002010-10-13T16:28:22.291+09:00Amazon Web Servicesによるソーシャルアプリ運用ノウハウ大公開<a href="http://gihyo.jp/magazine/SD/archive/2010/201011">Software Design 2010年11月号</a>にて、第1特集の「Amazon事例,国内新サービスから学ぶクラウド時代のシステム管理」の3章、「Amazon Web Servicesによるソーシャルアプリ運用ノウハウ大公開」という記事を執筆しました。<br />弊社がAWSを使いはじめたきっかけ、運用のポイント等をまとめてあります。<br /><br />また、第1特集の1、2章は弊社SREの石川が執筆してます。<br />こちらも弊社のAWS運用ノウハウをそのまま公開しています。<br /><br />10月18日発売です!<br /><br /><div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;margin:0px 12px 1px 0px;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B0044Z34Y6/horiuchiweblo-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/61GZJjno%2BoL._SL160_.jpg" alt="Software Design (ソフトウェア デザイン) 2010年 11月号 [雑誌]" style="border: none;" /></a></div><div class="amazlet-info" style="line-height:120%; margin-bottom: 10pjavascript:void(0)x"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B0044Z34Y6/horiuchiweblo-22/ref=nosim/" name="amazletlink" target="_blank">Software Design (ソフトウェア デザイン) 2010年 11月号 [雑誌]</a><div class="amazlet-powered-date" style="font-size:80%;margin-top:5px;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/B0044Z34Y6/horiuchiweblo-22/ref=nosim/" title="Software Design (ソフトウェア デザイン) 2010年 11月号 [雑誌]" target="_blank">amazlet</a> at 10.10.13</div></div><div class="amazlet-detail"><br />技術評論社 <br /></div><div class="amazlet-sub-info" style="float: left;"><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B0044Z34Y6/horiuchiweblo-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div></div></div><div class="amazlet-footer" style="clear: left"></div></div>horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-51608414346763196042010-07-07T12:55:00.002+09:002010-07-07T12:58:58.042+09:00第3回 AWS User Group - Japan 勉強会 で 発表します本日開催の<a href="http://atnd.org/events/6076">第3回 AWS User Group - Japan 勉強会</a>で「AWSによるソーシャルアプリ運用事例」という題で、発表してきます。<br /><br />gumiが運用しているソーシャルゲームの実際のサーバ構成やどうしてAWSを使うに至ったのかというような話をできればと思ってます。horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com2tag:blogger.com,1999:blog-1123743929918981950.post-7698609402589118792010-07-06T16:58:00.007+09:002010-07-06T17:30:38.787+09:00Amazon RDS で肥大化したslow_logテーブルをクリアする方法以前<a href="http://blog.hori-uchi.com/2009/11/amazonrdsslow-query.html">AmazonRDSでslow queryを出力するようにする方法</a>にてRDSでslow_logを出力するように設定すると、mysqlデータベースのslow_logテーブルにログが保存されるようになるのですが、このテーブルに保存されたデータは、RDSで作成できるユーザーの権限では削除することができません。<br /><br /><pre><br />mysql> delete from slow_log;<br />ERROR 1556 (HY000): You can't use locks with log tables.<br />mysql> truncate table slow_log;<br />ERROR 1044 (42000): Access denied for user 'xxxx'@'%' to database 'mysql'<br /></pre><br /><br />このことはgeneral_logにも言えるのですが、<br />これに対して、Amazonから以下のストアドプロシージャが提供されています。<br /><br /><pre><br />mysql.rds_rotate_general_log<br />mysql.rds_rotate_slow_log <br /></pre><br /><br />この2つのストアドプロシージャは新規、既存のものを含めて全てのRDSインスタンスで使用可能で、以下のようにCALL文により実行できます。<br /><br /><pre><br />CALL mysql.rds_rotate_general_log;<br />CALL mysql.rds_rotate_slow_log; <br /></pre><br /><br />プロシージャの中身はこんな感じです。<br /><pre><br />mysql> show create procedure rds_rotate_slow_log \G<br />*************************** 1. row ***************************<br /> Procedure: rds_rotate_slow_log<br /> sql_mode: <br />Create Procedure: CREATE DEFINER=`rdsadmin`@`localhost` PROCEDURE `rds_rotate_slow_log`()<br /> READS SQL DATA<br /> DETERMINISTIC<br />BEGIN<br /> CREATE TABLE IF NOT EXISTS mysql.slow_log2 LIKE mysql.slow_log;<br /> DROP TABLE IF EXISTS mysql.slow_log_backup;<br /> RENAME TABLE mysql.slow_log TO mysql.slow_log_backup, mysql.slow_log2 TO mysql.slow_log;<br />END<br />character_set_client: latin1<br />collation_connection: latin1_swedish_ci<br /> Database Collation: latin1_swedish_ci<br /></pre><br /><br />slow_logと同じスキーマのテーブル、slow_log2を作成し、既存のslow_logテーブルをslow_log_backupに、slow_log2をslow_logにリネームするという作業を行っています。<br />この際、slow_log_backupテーブルがすでに存在していればDROPしているので、この関数を2回呼ぶと、1回目にバックアップしたデータはなくなってしまうので注意が必要です。<br /><br />また上記の2つのプロシージャの他にKILL、KILL QUERYを実行できる以下の2つも用意されています。<br /><pre><br />mysql.rds_kill<br />mysql.rds_kill_query<br /></pre>horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-78470828064207720442010-06-30T14:28:00.002+09:002010-06-30T18:23:20.548+09:00Python × Django × AWSで作るソーシャルアプリ~3日に1つアプリをリリースできた理由~今日の19:30から「Python × Django × AWSで作るソーシャルアプリ~3日に1つアプリをリリースできた理由~」という題目で話をしてきます。<br /><br /><br />まだ空いてますので、お暇な方はぜひ!<br /><a href="http://atnd.org/events/4846">http://atnd.org/events/4846</a>horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com1tag:blogger.com,1999:blog-1123743929918981950.post-43841428598496617542010-06-14T10:53:00.002+09:002010-06-14T10:59:07.407+09:00第2回 AWS User Group - Japan 勉強会 で LTします。今日行われる<br /><a href="http://jaws-ug.jp/events/2zcqpf">第2回 AWS User Group - Japan 勉強会 - 6/14(月) </a><br />で「RDS multi AZ 早速試しました」というタイトルで、RDSとMulti-AZについて話をしてきます。<br /><br />Mult-AZ機能が搭載されて、実運用にも十分耐えれるようになったRDSについて、簡単に話をしようと思ってます。horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-36563374746843729892010-05-18T12:40:00.005+09:002010-05-18T17:42:46.201+09:00もう止まらない。Amazon RDS Multi-AZ Deployments機能をリリース本日、Amazon RDSの新機能、 Multi-AZ Deploymentsがリリースされました。<br /><br /><a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=3815&categoryID=291">Release: Amazon Relational Database Service on 2010-05-17</a><br /><br />これにより、RDSのダウンタイムがほぼ0になるという素敵な機能です!<br /><br />Multi-AZ deploymentを有効にするとプライマリDBとは別のAvailability Zoneにホットスタンバイとしてレプリカが作成されます。<br />レプリカはプライマリDBと同期していて、プライマリDBが止まると自動的にレプリカにスイッチします。<br />フェイルオーバーの仕組みはシンプルで、CNAMEレコードを変更し、スタンバイDBに向けるだけです。<br /><br />スタンバイDBに切りかわるタイミングは以下のとおりです。<br /><br /><ul><br /> <li>Availabilyty Zoneが落ちた時</li><br /> <li>プライマリDBが落ちた時</li><br /> <li>DBのスケールを変更した時</li><br /> <li>ソフトウェアにパッチを当てている時</li><br /></ul><br /><br />DBのバックアップ時に発生していたI/Oフリーズもなくなるようです。たぶんレプリカの方でバックアップを取るようになるのでしょう。<br /><br />また、レプリカには直接アクセスすることができないので、Read Onlyなクエリをレプリカに逃がすというスケールアウト的な使い方はできません。<br /><br />忘れてはならないコストですが、利用料は倍になります。<br />インスタンスが二つになるのでしょうがないと言えばしょうがないですね。<br /><br /><br />Multi-AZを適用する方法はすごく簡単です。<br /><br />まずは以下から最新版のコマンドラインツールをダウンロードして使えるようにします。<br /><br /><a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=2928&categoryID=294">Amazon RDS Command Line Toolkit</a><br /><br />バージョンが1.1.004ならOKです。<br /><pre><br />$ rds-version<br />Relational Database Service CLI version 1.1.004 (API 2010-01-01)<br /></pre><br /><br />あとは以下のコマンドを叩くだけで既存のインスタンスにMulti-AZ 機能を適用できます。<br /><pre><br />$ rds-modify-db-instance dbname --multi-az true<br /></pre><br />既存のインスタンスに適用すると、適用中に数分DBがダウンすると書かれているので、実行するタイミングには注意が必要です。<br /><br />実際試してみたところ、このコマンドを実行するとインスタンスにPending MultAZフラグが立ちます。(rds-describe-db-instancesコマンドで確認できます。)<br />僕の環境ではコマンド実行から数時間経過しましたがまだPending状態のままです。<br />PendingからMulti-AZが有効の状態になるにはかなり時間がかかりそうです。<br /><br />Pendingの状態でもDBには接続できているので、準備ができて、実際に適用するタイミングでちょっとばかりアクセスできなくなるんだと思います。<br /><br />また、新規作成の際も--multi-azオプションを指定してやるだけみたいです。<br /><br />これでますますRDSが手放せなくなりそうです。horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-39524900212276223282010-05-06T17:21:00.005+09:002010-05-06T18:10:14.066+09:00RDS バックアップから復旧する方法fooというRDSのインスタンスのバックアップからbarという新規インスタンスを作成する場合、以下のコマンドを実行する。<br /><br /><pre><br />$ rds-restore-db-instance-to-point-in-time bar -s foo -l<br /></pre><br />-sでソースにする元のインスタンスの名前(ここではfoo)を指定し、-lで復元可能な最新の時刻のバックアップから復元することを指定する。<br /><br />復元時刻を指定する場合は、-rオプションを使用する。<br />指定する時刻はUTC<br /><br /><pre><br />$ rds-restore-db-instance-to-point-in-time bar -s foo -r 2010-05-04T09:20:00Z<br /></pre><br /><br />リストア可能な最終時間はrds-describe-db-instancesに--show-longを指定することで確認できる。<br /><br /><pre><br />$ rds-describe-db-instances --show-long --headers<br />DBINSTANCE,DBInstanceId,Created,Class,Engine,Storage,Master Username,Status,Endpoint Address,Port,AZ,Backup Retention,PendingBackupRetention,PendingClass,PendingCredentials,PendingStorage,DB Name,Mainte<br />nance Window,Backup Window,Latest Restorable Time<br />DBINSTANCE,foo,2010-02-22T10:07:04.933Z,db.m2.4xlarge,mysql5.1,20,owner,available,foo.xxxxxxx.us-east-1.rds.amazonaws.com,3306,us-east-1a,1,(nil),(nil),(nil),(nil),(nil),tue:05:00-mon:09:00,<br />19:00-21:00,2010-05-06T08:45:00Z<br /></pre><br /><br />見づらいが、一番最後の2010-05-06T08:45:00Zが復元可能な最終時刻になる。<br /><br />バックアップが行われるのは1日1回だけだが、バックアップ後のトランザクションが全部保存されているので、それを元に直近1分前程度の状態を復元可能。<br />このため、バックアップから時間が経過していればしているほど、復元する際に時間がかかる。<br />特にDBの更新が頻繁だと復元に時間がかかる。<br />150 updates/sec程度の更新量で5時にバックアップを行っていた場合、9時に復元したところ、1時間程度、19時頃復元したところ、5時間くらいかかった。horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com1tag:blogger.com,1999:blog-1123743929918981950.post-54496391467764116222010-03-29T00:16:00.000+09:002010-03-29T00:17:27.502+09:00EC2のインスタンスにpingを通すためのセキュリティグループの設定<pre><br />ec2-authorize <group name> -P icmp -t -1:-1 -s 0.0.0.0/0<br /></pre>horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-48461583367002241162010-03-23T19:51:00.003+09:002010-03-23T20:01:04.300+09:00Djangoのパーミッションテーブルを更新するスクリプトDjangoでproxy modelというものを使って、ひとつのモデルを複数にわけて、<br />管理するようにした際に、片方のモデルがadminのユーザーパーミッション一覧に<br />表示されなくて困っていた。<br /><br />ユーザーパーミッションのテーブルを更新する方法がないかと<br />調べてみるとこんなページを発見<br /><br /><a href="http://www.djangosnippets.org/snippets/698/">http://www.djangosnippets.org/snippets/698/</a><br /><br />これを参考にパーミッションを更新するスクリプトを書いてみた。<br /><br /><pre><br /># -*- coding: utf-8 -*-<br />from django.core.management.base import BaseCommand<br />from django.contrib.contenttypes.management import update_all_contenttypes<br />from django.contrib.auth.management import create_permissions<br />from django.db.models import get_apps<br /><br /><br />"""<br />パーミッションを更新する<br />"""<br />class Command(BaseCommand):<br /> def handle(self, *args, **options):<br /><br /> # Add any missing content types<br /> update_all_contenttypes()<br /><br /> # Add any missing permissions<br /> for app in get_apps():<br /> create_permissions(app, None, 2)<br /><br /></pre><br /><br />これをインストール済みのアプリのmanagement/commands/syncpermissions.pyとして保存すれば、以下のコマンドで更新できる。<br /><br /><pre><br />$ python manage.py syncpermissions<br /></pre>horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-41203352993081036692010-02-22T10:44:00.003+09:002010-02-22T10:58:22.149+09:00gitでsubversionのようなショートカットを使えるようにする重い腰をあげて「入門git」を読んでます。<br /><br />今までsvkと同じような感じでgit commit -aばかり使ってたんですが、<br />ステージングエリアという概念を今さら知ったり、<br />ファイルの変更の一部だけコミットできるんだということを知ったり、<br />これもっと早く読んどけばよかったなーと、ちょっぴり後悔しています。<br /><br /><br />そんな中でgitコマンドのショートカットの設定方法が書いてあったのでさっそく設定しました。<br /><br /><pre><br />$ git config --global alias.ci "commit"<br />$ git config --global alias.stat "status"<br />$ git config --global alias.co "checkout"<br /></pre><br /><br />これで、git ci で git commitが、 git stat でgit statusが、git coでgit checkoutが実行できるようになりました。<br />快適。horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-67791958667602849662010-01-17T21:42:00.004+09:002010-01-17T21:49:07.553+09:00Amazon ELBを5つ以上作る方法ELBはデフォルトでは1アカウントあたり5つまでしか作れない。<br /><br />それ以上作ろうとすると以下のように怒られる。<br /><br /><pre><br />$ elb-create-lb test-lb --availability-zones us-east-1d --listener "protocol=HTTP, lb-port=80, instance-port=80"<br />elb-create-lb: Malformed input-Exceeded quota of account xxxxxxxxxx<br /></pre><br /><br />5つ以上作るためには、アマゾンに申請しないといけない。<br />申請は下記のフォームから行える。<br /><br /><a href="http://aws.amazon.com/contact-us/elb-request/">http://aws.amazon.com/contact-us/elb-request/</a>horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-66302089955145215222009-12-15T12:19:00.003+09:002009-12-15T12:29:16.155+09:00Shindig + Partuzaでキャッシュさせない設定Shindig + Partuzaで開発するならキャッシュ機能をオフにしないと不便。<br />Shindig,Partuzaの両方ともキャッシュに関する設定があるので、両方ともオフにする。<br /><br /><span style="font-weight: bold;">Shindig (PHP版)<br /></span><br />cache_timeを0に設定する。<br /><br /><pre><br />$ cat /path/to/shindig/php/config/local.php<br />'PartuzaService',<br /> 'activity_service' => 'PartuzaService',<br /> 'app_data_service' => 'PartuzaService',<br /> 'messages_service' => 'PartuzaService',<br /> 'oauth_lookup_service' => 'PartuzaOAuthLookupService',<br /> 'extension_class_paths' => '/Library/WebServer/Documents/partuza/Shindig',<br /> <span style="font-weight: bold; color: rgb(255, 0, 0);">'cache_time' => 0,</span><br /> );<br /></pre><br /><br /><span style="font-weight: bold;">Partuza<br /></span><br /><br />こちらもcache_timeを0に設定する。<br /><br /><pre><br />$ cd /path/to/partuza/html/<br />$ diff -u config.php.org config.php<br />--- config.php.org 2009-12-15 12:27:12.000000000 +0900<br />+++ config.php 2009-12-15 12:25:25.000000000 +0900<br />@@ -20,7 +20,7 @@<br /><br />$config = array(<br />// Language to use, used for gettext / setenv LC_ALL<br />-'language' => 'en_US',<br />+'language' => 'ja_JP',<br /><br />// prefix of where partuza lives, empty means it's /<br />'web_prefix' => '',<br />@@ -58,7 +58,7 @@<br />// If you use CacheStorageMemcache as caching backend, change these to the memcache server settings<br />'cache_host' => 'localhost',<br />'cache_port' => 11211,<br />-'cache_time' => 24 * 60 * 60,<br /><span style="font-weight: bold; color: rgb(255, 0, 0);">+'cache_time' => 0,</span><br /><br /></pre>horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-72207926701958278402009-12-14T16:08:00.003+09:002009-12-14T16:17:43.718+09:00デフォルトのストレージエンジンをInnoDBにするLeopardにdmgからインストールしたMySQLのデフォルトのストレージエンジンがMyISAMだってことに最近気付いた。<br />デフォルトのストレージエンジンを変更するにはmy.cnfでdefault-storage-engineを指定すればOK<br /><br /><pre><br />$ sudo vi /etc/my.cnf<br />$ cat /etc/my.cnf<br />[mysqld]<br />default-storage-engine=InnoDB<br /></pre><br /><br />mysqlを再起動して、実際にInnoDBになったか確認<br /><br /><pre><br />$ mysql -uroot<br />mysql> create database foo;<br />mysql> use foo<br />mysql> create table bar(id int not null);<br />mysql> show table status bar ¥G<br />*************************** 1. row ***************************<br /> Table: bar<br />Create Table: CREATE TABLE `bar` (<br /> `id` int(11) NOT NULL<br />) ENGINE=InnoDB DEFAULT CHARSET=latin1<br />1 row in set (0.00 sec)<br /><br /></pre>horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-12819680545675422652009-12-03T10:36:00.002+09:002009-12-03T10:42:44.797+09:00MySQL 主キーの追加・削除忘れるのでメモ<br /><br />主キーの追加<br /><br /><pre><br />ALTER TABLE テーブル名 ADD PRIMARY KEY (カラム名1[,カラム名2...]);<br /></pre><br /><br />主キーの削除<br /><br /><pre><br />ALTER TABLE テーブル名 DROP PRIMARY KEY<br /></pre><br /><br />削除時下のようなエラーがでたら制約を疑う<br /><pre><br />OperationalError: (1025, "Error on rename of './foo/#sql-b6f_3958' to './foo/bar' (errno: 150)")<br /></pre><br /><br />制約を確認<br /><br /><pre><br />mysql> SHOW CREATE TABLE foo;<br /></pre>horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-87766832978441500092009-11-24T16:15:00.007+09:002009-11-24T16:45:11.830+09:00AmazonRDSでslow queryを出力するようにする方法AmazonRDSは、デフォルトの設定ではslow queryを出力するようになっていない。<br />また、MySQLが動いているサーバにアクセスすることができないので、slow queryをログファイルに出力したとしてもそれを閲覧する術がない。<br />RDSでも採用されているMySQL 5.1からは、slow queryをテーブルに保存できるようになったので、それを使う。<br /><br />方針<br /><ul><br /><li>ログはテーブル(mysql.slow_log)に出力する。</li><br /><li>実行に1秒以上かかったクエリを記録する</li><br /><li>100行以上を読み込んだクエリを記録する</li><br /></ul><br /><br />普通なら以下のオプションをmy.cnfに設定すればOK。<br /><br /><pre><br />[mysqld]<br />slow_query_log = ON<br />long_query_time = 1.000<br />log_output = TABLE<br />min_examined_row_limit=100<br /></pre><br /><br />RDSの場合は、db-parameter-groupを作成し、パラメータを編集し、db-instanceに適用する。<br />今回はacme-param-grpというdb-parameter-groupを作成し、acmeというdb-instanceに適用する。<br /><br />db-parameter-groupを作成<br /><pre><br />$ rds-create-db-parameter-group acme-param-grp -e MySQL5.1 -d "parameter group for acme"<br /></pre><br /><br />db-parameter-groupのパラメータを編集<br />(log_outputはデフォルトでTABLEになっているので設定しない。設定しようとしてもできない)<br /><br /><pre><br />$ rds-modify-db-parameter-group acme-param-grp \<br />--parameters="name=slow_query_log, value=ON, method=immediate" \<br />--parameters="name=long_query_time, value=1, method=immediate" \<br />--parameters="name=min_examined_row_limit, value=100, method=immediate"<br /></pre><br /><br />methodに指定できる値はimmediate もしくは pending-reboot<br /><br />編集したパラメータの確認<br /><pre><br />$ rds-describe-db-parameters acme-param-grp --source user<br />DBPARAMETER long_query_time 1 user integer dynamic true<br />DBPARAMETER min_examined_row_limit 100 user integer dynamic true<br />DBPARAMETER slow_query_log 1 user boolean dynamic true<br /></pre><br /><br />sourceに指定できる値はuser 、system、 engine-default<br /><br />db-parameter-groupをdb-instanceに適用<br /><pre><br />$ rds-modify-db-instance acme --db-parameter-group-name=acme-param-grp<br /></pre><br /><br />db-instanceを再起動<br /><pre><br />$ rds-reboot-db-instance acme<br /></pre><br /><br />db-instanceにdb-parameter-groupが適用されているか確認<br /><pre><br />$ rds-describe-db-instances<br />DBINSTANCE acme 2009-11-04T10:59:28.860Z db.m1.large mysql5.1 100 xxxx available acme.xxxxxxx.us-east-1.rds.amazonaws.com 3306 us-east-1d 1<br /> SECGROUP xxxx active<br /> PARAMGRP acme-param-grp in-sync<br /></pre><br /><br />PARAMGRPがacme-param-grpになっていて、ステータスがin-syncになっていればOK。<br /><br />さらにmysqlにアクセスしパラメータが有効になっているか確認する。<br /><br /><pre><br />mysql > show global variables like 'slow_query_log';<br />+----------------+-------+<br />| Variable_name | Value |<br />+----------------+-------+<br />| slow_query_log | ON |<br />+----------------+-------+<br />1 row in set (0.00 sec)<br /><br />mysql> show global variables like 'long_query_time';<br />+-----------------+----------+<br />| Variable_name | Value |<br />+-----------------+----------+<br />| long_query_time | 1.000000 |<br />+-----------------+----------+<br />1 row in set (0.00 sec)<br /><br />mysql> show global variables like 'min_examined_row_limit';<br />+------------------------+-------+<br />| Variable_name | Value |<br />+------------------------+-------+<br />| min_examined_row_limit | 100 |<br />+------------------------+-------+<br />1 row in set (0.00 sec)<br /><br /></pre>horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-56053969035132306022009-11-20T20:36:00.003+09:002009-11-20T20:58:26.259+09:00Python 今日覚えたことutf-8な文字列を内部で扱う形式にデコードする際、<br /><br /><pre><br />unicode_str = utf8_data.decode('utf-8')<br /></pre><br />とするとutf8_dataにデコードできないバイト列があった場合、UnicodeDecodeErrorの例外をだす。<br /><br /><pre><br />UnicodeDecodeError: 'utf8' codec can't decode byte 0xb4 in position 1: unexpected code byte <br /></pre><br /><br />デコードできない文字列を削除してしまっていいのなら'ignore'を引数で渡してやればよい。<br /><br /><pre><br />unicode_str = utf8_data.decode('utf-8', 'ignore')<br /></pre><br /><br />さらにdecodeよりunicodeの方が高速らしい。<br /><br /><pre><br />unicode_str = unicode(utf8_data, "utf-8", 'ignore') <br /></pre><br /><br />エンコード、デコードの概念はPerlと同じなので理解しやすかった。<br /><br />参考<br /><a href="http://snippets.hachinos.net/lang/python/user/piro_suke/3/">http://snippets.hachinos.net/lang/python/user/piro_suke/3/</a><br /><a href="http://snippets.hachinos.net/lang/python/user/piro_suke/3/">http://d.hatena.ne.jp/methane/20090816/1250433407</a>horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-70676756380417545672009-11-18T18:39:00.002+09:002009-11-18T18:44:06.390+09:00saveをオーバーライドする時はforce_insert、force_updateを渡すDjangoでdjango.db.Modelsのsaveメソッドをオーバーライドする際<br /><br /><pre><br />def save(self):<br /></pre><br /><br />とすると、create()とget_or_create()で以下のようなエラーを吐いた。<br /><br /><pre><br />TypeError: save() got an unexpected keyword argument 'force_insert'<br /></pre><br /><br />saveにforce_insert,force_updateを渡すようにしないといけないらしい。<br />正解はこう<br /><br /><pre><br />def save(self, force_insert=False, force_update=False):<br /></pre><br /><br /><a href="http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges">http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges</a><br /><br /><blockquote><br />create() and get_or_create() will never update existing objects ¶<br /><br />In [8670] a change was made to both create() and get_or_create() that affects people in two ways:<br /><br />Firstly, if you have a custom save() method on your model and it is going to be called using create() or get_or_create(), you should make sure you accept the force_insert parameter (best to accept force_update as well, just like django.db.models.base.Model.save()). You don't have to do anything with these parameters, just pass them through to the Model.save() method. </blockquote>horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-73834192601865117892009-11-17T14:52:00.003+09:002009-11-17T15:13:04.739+09:00urllib2でgzipされたデータを扱うここに書いてあった。<br /><a href="http://diveintomark.org/projects/misc/httpgzip.py.txt">http://diveintomark.org/projects/misc/httpgzip.py.txt</a><br /><br />StringIOよりcStringIOのが高速でよいと聞いたのでそちらを使ってみる。<br />それ以外はまるパクリ。<br /><br /><pre><br /><br />import urllib2, gzip, cStringIO<br /><br />def get(uri):<br /> request = urllib2.Request(uri)<br /> request.add_header("Accept-encoding", "gzip")<br /> usock = urllib2.urlopen(request)<br /> data = usock.read()<br /> if usock.headers.get('content-encoding', None) == 'gzip':<br /> data = gzip.GzipFile(fileobj=cStringIO.StringIO(data)).read()<br /> return data<br /><br />if __name__ == '__main__':<br /> import sys<br /> uri = sys.argv[1:] and sys.argv[1] or 'http://mixi.jp/'<br /> print get(uri)<br /><br /></pre>horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com1tag:blogger.com,1999:blog-1123743929918981950.post-46402600367372668042009-11-13T11:38:00.004+09:002009-11-13T11:48:51.569+09:00MySQL 外部キー制約の追加、削除忘れるのでメモ<br /><br />MySQL 5.1で確認した。<br /><br /><span style="font-size:130%;">外部キー制約の確認</span><br /><blockquote><br />SHOW CREATE TABLE テーブル名;</blockquote><br /><br /><blockquote>show create table bbs_thread;</blockquote><br /><br /><span style="font-size:130%;">外部キー制約の追加</span><br /><blockquote><br /><span style="font-size:100%;">ALTER TABLE テーブル名 ADD FOREIGN KEY (制約を張りたいカラム) REFERENCES 張りたいテーブル(張りたいカラム);</span></blockquote><span style="font-size:100%;"><br /><br /><blockquote>alter table bbs_thread add foreign key (creator_id) references accounts_user(id);</blockquote><br /></span><br /><br /><span style="font-size:130%;">外部キー制約の削除</span><br /><br /><span style="font-size:100%;"></span><blockquote><span style="font-size:100%;">ALTER TABLE テーブル名 DROP FOREIGN KEY 制約名;</span></blockquote><br /><br /><blockquote>ALTER TABLE bbs_thread drop foreign key creator_id_refs_id_75448b6c;</blockquote>horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-57281560279211819572009-11-11T14:59:00.002+09:002009-11-11T15:03:09.047+09:00LeopardでcapistranoLeopardにはデフォルトでcapistranoが入っているが、バージョンが古いので、更新する<br /><br />$ sudo gem install capistrano<br /><br />複数環境にデプロイできるように。capistrano-extをインストールする<br /><br />$ sudo gem install capistrano-exthoriuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-33029932318652066452009-10-26T19:26:00.003+09:002009-10-26T19:33:26.451+09:00LeopardにPILをpipでインストール$ pip install PIL<br /><br />とすると<br />IOError: [Errno 2] No such file or directory: '/Path/to/build/PIL/setup.py'<br />というエラーがでてインストールできない。<br /><br />ソースのURLを指定してインストール。<br /><br />$ pip install http://effbot.org/downloads/Imaging-1.1.6.tar.gz<br /><br />Jpeg support not availableとログに出た場合は、<br />jpegを利用できるようにするために、libjpegをインストール<br /><br />$ wget http://www.ijg.org/files/jpegsrc.v7b.tar.gz<br />$ tar zxvf jpegsrc.v7b.tar.gz<br />$ cd jpeg-7<br />$ ./configure<br />$ make && sudo make install<br /><br />そんでもいっかいpip<br /><br />$ pip install http://effbot.org/downloads/Imaging-1.1.6.tar.gz<br /><br />JPEG support ok とでればOK。horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-90511631356163981742009-10-22T15:08:00.005+09:002009-10-22T16:02:42.149+09:00safari3でjTemplatesがうまく動かない問題を解決jTemplatesのsetTemplateElementメソッドを使ってテンプレートをロードする際、テンプレートに日本語が含まれていると、safari3では何も表示されないという問題に遭遇。<br />jQuery,jTemplatesのバージョンはそれぞれ現在最新の、1.3.2と0.7.8。<br /><br />原因を調べるため、jquery-jtemplates.jsを見てみると、なんのことはない、replaceの正規表現がうまくマッチせず、テンプレート内のコメント部分の除去がうまくいってないだけだった。<br /><br />具体的にはjquery-jtemplates.jsの中のjQuery.fn.setTemplateElement内にある下のコード。<br /><pre><br />s = s.replace(/^<\!\[CDATA\[([\s\S]*)\]\]>$/im,'$1'); <br />s = s.replace(/^<\!--([\s\S]*)-->$/im, '$1');<br /></pre><br /><br />これがsafari3だとうまくマッチせず、<!--と-->が除去されず、そのままコメント扱いになり、表示されていなかった。<br /><br />とりあえず、上記コードを下記のように修正することで対応した。<br /><br /><pre><br />s = s.replace(/^<\!\[CDATA\[/m, '').replace(/\]\]>$/m, '').replace(/^<\!--/m, '').replace(/-->$/m, '');<br /></pre>horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-1641963068368111102009-09-14T16:47:00.016+09:002009-09-14T17:40:07.406+09:00mixiアプリの表示領域(高さ)を調整する最適な方法mixiアプリの開発をはじめてからずっと表示領域(高さ)の調節に悩まされていたのですが、下記の記述でうまく調整されるようになりました。<br /><br /><blockquote style="font-weight: bold;"><span style="font-size:130%;">gadgets.window.adjustHeight($(document).height());</span></blockquote><br /><br />$(document).height()でjQueryを使ってdocumentの高さを取得し、<br />コンテナの提供するgadgets.window.adjustHeightに渡すようにしています。<br /><br /><br />そもそも、gadgets.window.adjustHeightは引数を渡さず実行すると、表示領域の高さを自動調整してくれるはずなので、引数なしで呼びだせばそれでOKなはずなのですが、これが結構うまく動作してくれません。<br />その結果コンテンツが全て画面に入りきらずに、スクロールバーが表示されてしまい、見づらいし、使いずらいということになってしまいます。<br /><br />ここで問題なのが、開発環境と本番環境で挙動が異なるということで、<br />僕の場合ローカルの開発環境(Partuza+Shindig)では高さの自動調整がうまく行くのに、mixi上で動作させると高さがうまく調整されずスクロールバーがでてしまうという現象になやみました。<br /><br />そこで上記の解決策です。jQueryで高さを取得することで、コンテナに依存しなくなるので、開発環境でも本番環境でも同じ挙動を得ることができるようになりました。<br /><br />コンテナが成熟してくればこの手の問題はある程度解決していくとは思いますが、コンテナ毎の微妙な差異というのは少なからず残るのではないかと思います。<br /><br />そのため、今回のようにコンテナに依存しないような方法を取るというのは、様々なプラットフォームで動かすアプリを作る時には考えなければいけないなと思います。horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-1146902634315733042009-06-04T04:12:00.000+09:002009-08-23T22:54:55.029+09:0010日でおぼえるPython入門教室CMSコミュニケーションズの寺田さんから「10日でおぼえるPython入門教室」を献本いただきました!<br/>どうもありがとうございます!!<br/><br/>ちょうど僕の中で「Python」が熱くなっていたところだったんです!<br/>まさにベストなタイミング!<br/><br/>10日目にはGoogle App Engineの使い方の解説もあるみたい。<br/>これからじっくり読んでみます。<br/><br/><br/><div class="amazlet-box" style="margin-bottom:0px;"><div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4798118753/horiuchiweblo-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51iy-nMV8aL._SL160_.jpg" alt="10日でおぼえる Python 入門教室" style="border: none;" /></a></div><div class="amazlet-info" style="float:left;margin-left:15px;line-height:120%"><div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4798118753/horiuchiweblo-22/ref=nosim/" name="amazletlink" target="_blank">10日でおぼえる Python 入門教室</a><div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4798118753/horiuchiweblo-22/ref=nosim/" title="10日でおぼえる Python 入門教室" target="_blank">amazlet</a> at 09.06.03</div></div><div class="amazlet-detail">穂苅 実紀夫 寺田 学 中西 直樹 堀田 直孝 永井 孝 <br />翔泳社 <br />売り上げランキング: 5963<br /></div><div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4798118753/horiuchiweblo-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div></div><div class="amazlet-footer" style="clear: left"></div></div><br/><br/><br/><br/>horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0tag:blogger.com,1999:blog-1123743929918981950.post-4883824148696346382009-03-14T10:43:00.000+09:002009-08-23T22:54:55.030+09:00OpenPNE flipclip小窓スクリプト 新URL対応版FlipClpリニューアルに伴って、クリップのURLを下記のように変更しました。<br/><br/>旧URL<br/>><pre><br/>http://www.flipclpi.net/{userid}/{clip_no}<br/></pre><<br/><br/>新URL<br/>><pre><br/>http://www.flipclpi.net/{clip_no}<br/></pre><<br/><br/>旧URLから新URLへはリダイレクトするようにしているので旧URLはそのままにしておいて問題ないのですが、クリップのURLを正規表現でマッチさせてごにょごにょしたりしている場合、新URLだとマッチせずうまく動かないってことがおこっちゃってます。<br/><br/>OpenPNEの小窓機能もそのひとつで、新URLを貼り付けるとうまくURLがマッチせず、動画が表示されなくなってしまってます。<br/>OpenPNEの中の人が対応してくれると思いますが、取り急ぎ、新URLでも動くものをのっけておきます。<br/>以下のflipclip.net.js、www.flipclip.net.jsをダウンロードして、public_html/cmd/に上書きコピーすればOKです。<br/><br/>><pre><br/>OpenPNE flipclip小窓スクリプト 新URL対応版<br/><a href="http://hori-uchi.com/misc/flipclip.net.js">flipclip.net.js</a><br/><a href="http://hori-uchi.com/misc/www.flipclip.net.js">www.flipclip.net.js</a><br/></pre><<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>horiuchihttp://www.blogger.com/profile/10139525039076752147noreply@blogger.com0