カスタム検索

2009年2月27日金曜日

mySQLレプリケーションのセットアップ

もっぱらpostgresだったのだけんども食わず嫌いも良くないのでmySQLをもしゃもしゃしてみた。
このへんを参考に。

・セットアップ
Macはパッケージがあるので簡単セットアップで完了。
postgresでいう所のpgAdminはmySQL GUI TOOLというのがある。

サーバ管理系とクエリ/データ処理系とで以下の二つに別れている。

・MySQL Administrator
DBの起動/停止、DBの作成、テーブルの作成、ユーザの作成、バックアップ/リストア等がGUIで出来るツール

・MySQL QueryBrowser
クエリの実行、テーブルの中身をざっくりみたい場合もこっち


サクっと起動した所で、レプリケーションの設定。
スレーブ側からマスタへ接続する為のユーザを作成。
  1. mysql> GRANT REPLICATION SLAVE ON *.* TO repl@'192.168.20.0/255.255.255.0' IDENTIFIED BY 'xmldo';  

repl / xmldo というユーザが作成される。
この接続は 192.168.20.0/24 からのみ接続可能。
MySQL Administratorから作る事も出来る。

マスタ側はログをバイナリで出力する必要がある。
また、レプリケーションする際には、すべてのDBへ固有のserver-idが必要となる。
マスター側のmy.cnf
  1. [mysqld]  
  2. server-id=10  
  3. log-bin  


スレーブ側のmy.cnf
  1. [mysqld]  
  2. server-id=11  
  3. master-host=192.168.20.15  
  4. master-user=repl  
  5. master-password=xmldo  


設定ファイルを書き換えて再起動でレプリケーション完成。あら、アッサリなのね。
ではトラブルを想定して実験をしてみましょう。

・スレーブが停止中にマスターにデータが書き込まれ、その後スレーブが復帰。
>スレーブ復旧後に、追加したデータ問題なく挿入されました。

・マスターが停止中にスレーブにデータが書き込まれ、その後マスターが復帰。
>標準のレプリケーションはマスタ/スレーブ方式なので、復旧しない。

なんらかのトラブルでスレーブを使う事になったら、マスタ復旧時にはスレーブをバックアップ>マスタへリストアしてやる必要がある、と。
ここでマルチマスタ方式のmySqlClusterを使うのだろうけど、とりあえずバックアップをとっておきたいの場合はこれでも十分だろう。
(なんといっても設定が簡単だし・・・)

データだけを別システムで流用(リードオンリーで)するような場合は良いっすね。

2009年2月14日土曜日

jQueryを使ってみた

乗るしかない、このビックウェーブに
という事で食わず嫌いだったjQueryを使ってみました。

grailsのwikiでページ一覧をツリーで表示したいというのがあったので、そこを目標に、というかすでにやっつけで作ってコミットしてあります。

本家からjQuery本体をダウンロード
ツリーで調べたらjQueryFileTreeというのがあったのでこれをチョイス。
pluginでjQuery Easing Pluginか、相当するものが必要ということでこれもダウンロード。

pluginってどうするのかなーと思っていたけど、本体をロードした後にロードするだけでいいみたい。

以下まずはjQueryを使って感じた事メモメモ
・prototypeでいう$("elementId")は$("#elementId")で取得
・prototypeでいうForm.serialize()はformエレメントの.serialize()で出来る。
 (formがドキュメント上に1個しかなければ $("form").serialize() でおk)

・ajax処理は以下の感じ
  1. var params=$("form").serialize();  
  2. $.ajax({  
  3.   url:"${createLink(controller:'hoge',action:'foo')}",  
  4.   type:"post",  
  5.   data:(params),  
  6.   success: function(request) {  
  7.     $('#success').html(request);  
  8.   }  
  9. });  


・安全なドキュメントロード後のinit処理
$(document).ready(function() {});

エレメントにイベント追加(クリックを例に)
$("#elementId").click(function(){});

イベントの追加が自然でいい感じ。
extのStoreみたいなのはあるのかなー、あれ凄く好きだったんだけど・・・

ツリーの実装はまた今度

2009年2月12日木曜日

Hudson最強化計画

HudsonをCI以外で使うというブログを読んで強カットインが入った。

そうだよなー、データベースのバックアップをやれば失敗でメールを投げたり、色んなバックアップをまとめて管理しておけるし、バックアップログも残しておけるし、システム稼働監視なんかも出来るじゃまいか。
何よりもそれらが統一されたGUIで行えるわけで、サーバに入り込んでどこで何やってるか把握する必要もなく、Linuxの知識もそれほどいらない。

いやー、こういう使い方は凄く良いと思う!

2009年2月5日木曜日

Grails+BlazeDSでファイルアップロード

FileReferenceを使ったアップロードでは browse() が必須になります。
ファイルを選択してアップする場合は問題ないのですが、決まったファイルのアップロード(別システムから出力されるデータなど)を行う場合には不便です。

なのでBlazeDSでアップロードしてやりましょう。
GrailsでBlazeDSは過去のエントリを参照に。

BlazeDSではActionScriptの byte[] と Java の byte[] をコンバートして通せるようなので、ファイルをbyteにして投げてやります。
  1. private function blazeDsUpload():void {  
  2.   // ファイルをバイト配列で読み込む  
  3.   var file:File=new File("/opt/hoge.jpg");  
  4.   var fs:FileStream=new FileStream();  
  5.   var bytes:ByteArray=new ByteArray();  
  6.   fs.open(file, FileMode.READ);  
  7.   fs.readBytes(bytes, 0, file.size);  
  8.   
  9.   //定義してあるRemoteObjectへパラメーターとして渡す  
  10.   remoteObject.upload({"Filedata":bytes});  
  11. }  


Grailsのサービス側で受け取るサンプル
byte[]データをファイルへ収めてやります。
  1. def upload(params) {  
  2.   def fileBytes=params["Filedata"]  
  3.   def file=new File("/work/hoge.jpg")  
  4.   file.withOutputStream { out ->  
  5.     out.write(fileBytes)  
  6.   }  
  7. }  

2009年2月4日水曜日

Air+Grailsでファイルアップロードの巻

AirにはFileReferenceというアップロード用のクラスが用意されてますので、そいつを使います。

  1.  var fileRef:FileReference=new FileReference();  
  2.  fileRef.addEventListener(Event.SELECT,selectHandler);  
  3.  fileRef.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);  
  4.  fileRef.browse();  
  5.   
  6. // ファイル選択後アップロード処理を実行  
  7. private function selectHandler(event:Event):void {  
  8.   var file:FileReference = FileReference(event.target);  
  9.   var uploadURL:URLRequest = new URLRequest();  
  10.   uploadURL.url = "http://localhost:8080/grails/sample/upload";  
  11.   file.upload(uploadURL);  
  12. }  
  13.   
  14. // これがないとエラー画面が出ました  
  15. private function ioErrorHandler(event:IOErrorEvent):void {  
  16. }  


Grails側に受けのアクションを作ってやります。
普通にMultiPartFormDataが来るので、処理してやるだけです。
  1. class SampleController {  
  2.   def upload={  
  3.     def file=request.getFile("Filedata")  
  4.     file.transferTo(new File("/hoge",params["Filename"]))  
  5.   }  
  6. }  

2009年2月3日火曜日

grails run-app が永久ループする件について

前にrun-appした時に、起動後永遠とリロードを繰り返して動かないという状況がありました。
その時はinteractiveでrun-appした時はちゃんと動くので、そのままにしてたのですが、最近ふとしたきっかけで解決しました。

groovyファイルとかjavaファイルとかを実行時にコンパイルするのですが、
packageが指定してある場合に、packageと実際にフォルダ位置があっていない場合に上記の症状が発生します。
多分生成するclassと実際のソースパスが一致しないため、いつまでも新規ファイルが投入されたと思ってコンパイルを繰り返すものと思われます。

なんでpackage名とフォルダ構成をあわせてやるだけでOKです。


まったく関係ない話ですがアップルとアドビが組んでiPhone用Flashを開発中という話
ってーことはflexアプリとか動いちゃうんかいなー?アプリ形式に対応すればAppStoreへの登録も可能なわけで :)
もの凄く夢が広がりんぐ!
Androidの方はどうなんだろ、Flashには対応してるみたいだけどアプリ的に扱えるようになればおもしろいですね。
Android/iPhoneのマルチプラットフォームアプリケーション開発とか出来たらかっこいいな〜
adobe labsが出来た辺りからadobeには色々とワクワクさせられます。