デイリーのアクセスを取得
次に、デイリーのアクセスを取得するコードです。取得するColumnFamilyやColumnが違っているくらいで、基本的にはアワリーの場合と変わった部分はありません。
// デイリーのアクセスを取得する
public List<Access> getDailyCount(String domain, String path, Calendar startDay, Calendar endDay) throws IOException {
// Scanの作成
Scan scan;
String reversedDomain = reverseDomain(domain);
if (path != null) {
byte[] row = createRow(reversedDomain, path);
scan = new Scan(row, row);
} else {
byte[] prefix = Bytes.toBytes(reversedDomain);
scan = new Scan(prefix);
scan.setFilter(new PrefixFilter(prefix));
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
// startDayとendDayから取得したいColumnを指定
Calendar cal = (Calendar) startDay.clone();
while (cal.before(endDay)) {
scan.addColumn(DAILY_COLUMN_FAMILY, Bytes.toBytes(sdf.format(cal.getTime())));
cal.add(Calendar.DAY_OF_MONTH, 1);
}
// 結果の取得
List<Access> ret = new ArrayList<Access>();
HTableInterface table = hTablePool.getTable(TABLE);
try {
ResultScanner scanner = table.getScanner(scan);
for (Result result : scanner) {
String[] domainAndPath = extractDomainAndPath(result.getRow());
for (Map.Entry<byte[], byte[]> entry: result.getFamilyMap(DAILY_COLUMN_FAMILY).entrySet()) {
byte[] qualifier = entry.getKey();
byte[] value = entry.getValue();
// 時間
Calendar time = Calendar.getInstance();
time.setTime(sdf.parse(Bytes.toString(qualifier)));
// Accessオブジェクトの作成
Access access = new Access();
access.setTime(time);
access.setDomain(reverseDomain(domainAndPath[0]));
access.setPath(domainAndPath[1]);
access.setCount(Bytes.toLong(value));
ret.add(access);
}
}
} catch (ParseException e) {
// 省略
} finally {
table.close();
}
return ret;
}
トータルのアクセスを取得
最後に、トータルのアクセスを取得するコードです。これも、基本的にはアワリーやデイリーのコードと同様になります。
ただしトータルのアクセスの場合、年月日などの情報がないので、Columnを限定する処理はありません。
// トータルのアクセスを取得する
public List<Access> getTotalCount(String domain, String path) throws IOException {
// Scanの作成
Scan scan;
String reversedDomain = reverseDomain(domain);
if (path != null) {
byte[] row = createRow(reversedDomain, path);
scan = new Scan(row, row);
} else {
byte[] prefix = Bytes.toBytes(reversedDomain);
scan = new Scan(prefix);
scan.setFilter(new PrefixFilter(prefix));
}
scan.addFamily(TOTAL_COLUMN_FAMILY); // ColumnFamilyを限定する
// 結果の取得
List<Access> ret = new ArrayList<Access>();
HTableInterface table = hTablePool.getTable(TABLE);
try {
ResultScanner scanner = table.getScanner(scan);
for (Result result : scanner) {
String[] domainAndPath = extractDomainAndPath(result.getRow());
// Accessオブジェクトの作成
Access access = new Access();
access.setDomain(reverseDomain(domainAndPath[0]));
access.setPath(domainAndPath[1]);
access.setCount(Bytes.toLong(result.getValue(TOTAL_COLUMN_FAMILY, HConstants.EMPTY_BYTE_ARRAY)));
ret.add(access);
}
} finally {
table.close();
}
return ret;
}
まとめ
今回は、HBaseを使って簡易アクセス解析サービスを作成しました。前回に比べて、比較的シンプルで分かりやすかったのではないでしょうか。次回も引き続き、HBaseを使ったアプリケーションの別のケーススタディを紹介する予定です。
また、株式会社サイバーエージェントでは、Hadoop/HBaseエンジニアを募集しています。ご興味のある方はこちらからエントリーしていただければと思います。エンジニア>R&Dエンジニア>R&Dエンジニアを選択しエントリーしていただければ幸いです。
参考資料
この記事は参考になりましたか?
既に会員の方はを行ってください。
- 初めてのHBase連載記事一覧
- この記事の著者
-
鈴木 俊裕(スズキ トシヒロ)
株式会社サイバーエージェント アメーバ事業本部 Ameba Technology Laboratory 2008年4月に株式会社サイバーエージェントに新卒で入社。基盤システムの開発・運用に従事する。 2010年4月にHadoop/Hiveを用いたログ解析基盤の開発・運用を担当する。 2011年4月に、ログ解析、レコメンド、検索エンジンなどを開発するAmeba Technology Laboratoryの立ち上げメンバーとなる。 2011年10月からHBaseを用...
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
