背景
正直なところ、私はこれまでに掲示板で中古品を購入したことがありません。 しかし、次の経済危機が起こり、その必要性が強まったとき、私はアビトに注意を向けなければなりませんでした。
提案を調べたとき、いくつかの広告が低価格、不正確な説明など、いくつかの兆候のために疑わしいように見えたことがすぐに印象的でした。 過去の画像がすぐに私の記憶に現れました。90年代のフリーマーケットで、購入と空のポケットまたはカットバッグの両方で返品できました。
ご存知のように、Avitoは販売者の他の広告に関する情報を提供していません。そのため、広告のテキストでは、購入者が検索に使用できるキーワードまたはハッシュタグがよく使用されます。 ただし、配置規則に記載されているように、Avito政権は、販売の主題に関連しない情報の発表の本文に存在することを歓迎していないことに注意する必要があります。 配置ルールに違反した場合、Avitoは広告と売り手のアカウントの両方をブロックする場合があります。
検索エンジンは、主に中古車に関連するAvitoやその他の掲示板に寄生するいくつかのサイトを提供してくれました。 ほとんどの場合、事前にダウンロードされた広告のデータベースで、販売者の電話番号で検索広告を提供します。 それらにはすべて、私にとって重要な欠点があります:複雑なインターフェース、有料サービス、一定の遅れでデータを更新します。
情報への無料アクセスに関するStephen Levyの意見を共有し、Avitoを分析して、ブラックジャックとすべての問題、つまりシンプルなインターフェースと無料アクセスを備えた独自のsravnito.ruサービスの開発を決定しました。
分析に基づいて、広告の主な属性が特定されました。
- 名前
- 発行日
- 価格
- 場所
- 電話番号(番号の画像、またはそのハッシュ、または認識されるOCR値)
建築
次に、すべての売り手の広告の検索サービスのベースとなるソフトウェア複合体のアーキテクチャについて直接説明します。
保管
InnoDBエンジンを備えたMySQL(Maria DB)は、広告とそのスクリーンショットを保存するためのストレージとして使用されます。
DB1は、基本属性を持つ宣言を保存します。 データが占有するメモリ量を減らすため、テキストフィールドには長さが広告ごとに異なるため、VARCHAR型がテキストフィールドに使用されます。 毎日約50万行が追加されますが、その中には広告自体とログおよびサービス情報の両方が含まれます。 このようなダイナミクスにより、ストレージは当然ビッグデータに起因します。 以下のパラメーターは、構成機能と区別できます。
max_heap_table_size = 512M innodb_buffer_pool_size = 3G
ヒープ上のテーブルは、一時テーブルでデータが最初に選択されるときに、いくつかの大きなテーブルからのクエリを最適化するために使用されます。
CREATE TEMPORARY TABLE _temp_table ENGINE=MEMORY AS ( SELECT field FROM table WHERE key = i_key LIMIT i_limit);
次に別のものに接続します:
SELECT table.* FROM table JOIN _temp_table ON table.field = _temp_table.field;
DB2は、ブラウザユーザーに表示される広告のスクリーンショットを保存します。 記録する前に、スクリーンショットは品質= 5のJPEGで圧縮され、約20Kbの画像でファイルサイズが確保されます。 BLOBサイズが200 KB以下の場合、MySQLのファイルストレージのパフォーマンスはNoSQLストレージよりも劣らないことが一般に受け入れられています。これにより、すべての利点を備えたリレーショナルDBMSの快適ゾーンに留まることができます。 このような圧縮されたスクリーンショットは、最低の画像品質にもかかわらず、指定された広告が実際に存在したことを確認し、製品の少なくとも概略図を見ることができます。
すべてのロジックはストアドプロシージャに実装され、DBMS自体のデータ構造に依存するコードをカプセル化します。 したがって、DBMSクライアントには、べき等のストアドプロシージャへのアクセスのみが許可されます。 追加のプラスとして、SQLインジェクションの可能性が不足しています。
ストレージAPI
M1サーバーはgolangマイクロサービスとして実装され、広告、スクリーンショットを保存し、広告の検索エンジンのページに表示されるデータを読み取るためのRESTful APIを提供します。 フレームワークまたは外部ライブラリを使用してgolangにRESTfulを実装する理由はないため、1つを除き、標準ライブラリのみが使用されます。
import ( "database/sql" "encoding/json" "net/http" _ "github.com/go-sql-driver/mysql" )
クライアントからのGETおよびPOST要求が処理され、対応するDB DB、DB2データベースストアドプロシージャが呼び出されます。
広告ローダー
広告は、Selenium WebDriverライブラリを使用してJavaで記述されたS(1)-S(N)ダウンローダーによってAvitoサイトからダウンロードされます。 Avitoから広告属性とスクリーンショットを受け取ったローダーは、データ転送のためにM1サーバーに接続します。 また、「stop」、「start」などのコマンドについてM1サーバーを定期的にポーリングするブートローダーを制御するフィードバックが実装されています。
キャプチャ
Avitoが時々要求するキャプチャを解決するために、golangに実装され、RESTful APIを提供する、M1サーバーと同様のC1サーバーがあります。 キャプチャを解決するには2つの方法があります。
- rucaptcha.comを使用する
- Androidアプリケーションで手動で
彼らのAPIはrucaptcha.comへの連絡に使用されます。 手動での解決には、Javaで記述されたJavaアプリケーションが使用されます。これは画像を表示し、回答を受け取ります。 C1サーバーは、キューに蓄積されたリクエストの数に応じて、captchaをrucaptcha.comまたはAndroidアプリケーションにリダイレクトすることを決定します。 キャプチャの手がかりを受け取ったサーバーC1は、要求しているローダーに応答を送信します。
モニタリング
キャプチャを解決するためのAndroidアプリと同様に、監視アプリケーションがあります。 Android監視アプリケーションはM1サーバーにアクセスし、M1サーバーはログが集計されるデータベースにアクセスします。このデータベースに基づいて、読み込まれた広告の数、誤動作などを判断できます。
おわりに
サービスのさらなる開発は次のとおりです。
- 他の掲示板用のダウンローダーを作成します。これにより、1人の売り手のすべての広告を横断検索できます。
- 複合体を使用して他のデータを処理する。たとえば、ソーシャルネットワークからダウンロードして、アカウント名ですべての投稿を検索する
どちらの場合も、M1およびC1サーバーと簡単に統合できる開発対象はブートローダーのみです。 システムの他の部分を改良する必要はありません。
M1、C1サーバーのAPIを承認付きで公開し、クライアントごとにデータベース構造に分割するためのキーフィールドを追加すると、データを保存し、キャプチャをSaaSとして処理するサービスを提供できます。 クライアントデータはJSONの形式でBLOBに格納できますが、ストアドプロシージャとAPIを使用してデータベースをファイナライズします。
選択したテクノロジーについて言えること:
- MySQL-ジャンルの古典、コメントなし
- Java-ローダーはコーヒーメーカーと冷蔵庫で実行できます
- golang-マイクロサービスは非常に迅速に開発され、単一のバイナリをサーバーにコピーすることで簡単に展開できます
コメントと議論をお願いします。