2016-05-04 10 views
0

正確な時刻同期が重要なプラットフォーム(+/- 0.01秒)を構築しています。 AWSについての私の理解によれば、複数のサーバーインスタンス間のクロックドリフトが本当の問題になる可能性があります。しかし、私は、スケールアップしてもRDSがクロックドリフトに悩まされないと言われてきました。結果として私はライブに行くときにRDSを使用する予定で、Carbon :: now()を使用するのではなく、データベースクエリを使用してnow()をプルしようとしています(Apacheサーバーから時間がかかる)。だから私は予備的な質問があると思う:私は何かを逃したか?それはうまくいくのだろうか?私が無視したより良いアプローチはありますか?私のアプローチを想定しAWSクロックドリフトを回避するためにLaravel 5のデータベースサーバからnow()を取得

は、私は次のことをクリーンアップしようとしている、正しいです:

$currentTime = DB::select(DB::raw('SELECT NOW()')); 

まず第一に、ちょうど厄介に見えると私はきれいな方法があります確信していること。第二に、代わりに私のタイムスタンプを与えるのではなく、このようになります配列を返すだ:

Array 
(
    [0] => stdClass Object 
     (
      [NOW()] => 2016-05-04 14:03:49 
     ) 
) 

を私が使用してみました - (第一>)と - >(取得)が、どちらも働いていた(両方ともエラーが発生します)。私はこれをどのように扱うべきですか?

+0

私が次のようにすれば、出力が得られますが、それでもなお驚くほど厄介に見えます: $ serverTimeArray = DB :: select(DB :: raw( 'SELECT NOW(3)AS now')); $ serverTime = $ serverTimeArray [0] - >今すぐ; – jreikes

答えて

0

これは当初予想していたよりもやっかいなことです。 LaravelはPDOを使用してMySQLに接続します。 MySQLは現在、小数点以下6桁の精度でDATETIMEをサポートしていますが、PDOはDATETIMEで1秒の小数点以下をサポートしていません(「WTF?」は正しい応答です)。私が後にしている精度でデータを取得して保存するには、ギアを変更してUnixの時刻形式(1970年1月1日以降の秒数)を使用する必要がありました。私はデータベースにDECIMAL(18,3)カラムとして格納しています。これは、私が後にしたミリ秒の精度のための余裕を与えてくれます。

私は上記のコードセクションは、以下のようになります。

$serverTimeArray = DB::select(DB::raw('SELECT UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) AS now')); 
$serverTime = $serverTimeArray[0]->now; 

これは実際に私の時間操作の多くを作る(時間を加算/減算)かなり容易になります。

私は今、別の質問を投稿する必要があるかもしれない、新しい無関係の問題がありますが、動作しているようです...

1

2つのもの。

まず、クロックドリフトがAWSの問題であることには注意が必要です。それはAWSとは関係ありません。サーバークロックがドリフトします。そのため、のサーバーにはのサーバーに常にntpdをインストールする必要があります。なぜなら、その問題は効果的にサーバー自体を処理するためです。 (RDSの時計はどのように正確に推測されていると思いますか?)ntpdを、常に、常に、常に、私たちのサーバーにインストールしてください。

第2に、NOW()は定義上+/- 0.500秒の誤差があります。本当に、それは+ 0/-0.999999に似ています。なぜなら、実際には現在の時刻より後で表示されることは決してないからです...しかし、ここのオリジナルのソリューションは、あなたが必要とするものを提供しません...しかし、単一の権威ある時間源を有すると言われて、おそらくデータベースがおそらく最善の候補です。 RDSマシンがMySQL 5.6以降の場合は、ミリ秒ではSELECT NOW(3)、マイクロ秒ではSELECT NOW(6)と考えてください。

また、1つのイベントが別のイベントより先に発生したかどうかを判断するための信頼できる単調カウンタが必要な場合は、UUID_SHORT()を調べます。これは、64ビットカウンタで、毎回1ずつ増加します。また、データベースサーバがリブートされるたびに前に飛びますが、サーバが起動するたびにデータベースサーバの時計が正しい限り、それは決して後退しません。

+0

それは非常に良いフィードバックです。実際の時間に対する精度はそれほど必要ではありませんが、権威のある時間源を1つ(それを置いた場合)持つことは非常に重要です。 NOW(3)は私にとって正しい答えのように聞こえます。今、私はLaravel構文を理解する必要があります。 – jreikes

+0

列のエイリアシングを試みてください。 'SELECT NOW(3)AS server_time'。 –

+0

列にエイリアスを設定しても、クラスまたは配列を取得する問題は解決されません。これは返された配列の "NOW()"ラベルを変更するだけです。 – jreikes

関連する問題