環境
Web アクセス ログを解析する場合、ボットを人間のユーザー エージェントから分離する必要があります。
それらのリストを手動で作成し、ボットのようなパターン (たとえば、botを含む) を抽出しました。次に、受信アクセス ログをリアルタイムで検証するパターンのリスト (最大 300 項目) を取得します。私の (非効率的な) アルゴリズムが任意のパターンを探すため、時間が経つにつれて、これはかなりのボトルネックになりました。DoS に対する脆弱性を意味するパフォーマンスの低下を無視したとしても。
コード (Java)
String userAgent;
List<Pattern> botPatterns;
for (Pattern botPattern : botPatterns)
{
if (botPattern.matcher(userAgent).find())
{
return true;
}
}
return false;
すでに調査済みの回答
WURFL を使用して
これは単純な解決策かもしれませんが、結果が不正確になることがあります。今のところ、組み込みのソリューションは避けたいと思います。
ユーザーエージェントのキャッシュを使用する
ユーザー エージェント文字列をハッシュマップに格納することで、結果をキャッシュすることができます。ただし、これによりパフォーマンスは向上しますが、ランダムに生成されたユーザー エージェント文字列による単純な DoS 攻撃に対する脆弱性が高まります。
質問
一定数の正規表現パターン (m) に対して多数 (N) の文字列を照合する効率的なアルゴリズムはありますか?
編集:ベンチマーク回答
実際のデータと、ランダムに生成されたユーザー エージェント文字列を使用して、@stemm の回答をベンチマークしました。テストを 10 秒間実行し、計算時間を平均しました。キャッシュは、サイズ 5000 の単純な LFU ehcache です。
ここに私の結果があります:
パターンループ
キャッシュなし
実際のデータ: 101us
ランダムデータ: 193us
キャッシュあり
実際のデータ: 4us
ランダムデータ: 203us
単一のパターン
キャッシュなし
実際のデータ: 100us
ランダムデータ: 160us
キャッシュあり
実際のデータ: 3us
ランダムデータ: 154us
結論
- 実際の状況では、キャッシングが最も効果的なソリューションです。
- 1 つのパターンを使用すると、複数のパターンをループする場合に比べて 25% のゲインが得られます。
- キャッシュは、私が思っていたほど DoS に対して脆弱ではありません。
人々の回答とコメントに感謝します。