プロンプトとスコープ
イベントレイクは、収集タイムスタンプをナノ秒の精度で保持する必要があります。テーブルはIceberg v3を使用し、バッチ、ストリーミング、およびBIエンジンから読み取られます。タイムゾーン付きとタイムゾーンなしのタイムスタンプ型の違い、書き込み時の検証、古いリーダーとの互換性、およびリバーシブルな移行について説明してください。
面接官がテストしていること
- v3でミリ秒フィールドの名前が変更されたのではなく、
timestamp_nsとtimestamptz_nsが追加されたことを理解しているか。 - 市民時と絶対的な瞬間を区別し、オフセットを正しく処理できるか。
- 切り捨て、負の時刻、およびシリアライズのリスクを認識しているか。
- クロスエンジン機能マトリックスとロールバックパスを設計できるか。
明確化のための質問
- ナノ秒の精度は順序付けに必要ですか、それとも監査用の表示のみですか?
- その値は1つのグローバルな瞬間を表していますか、それともローカルのカレンダー値を表していますか?
- ライター、カタログサービス、およびリーダーは、どのIceberg v3バージョンをサポートしていますか?
- 古いシステムがミリ秒しか読み取れない場合、明示的に精度を落としたカラムを使用してもよいですか?
30秒の回答
意味に基づいて選択します:timestamp_nsはタイムゾーンを持たず、timestamptz_nsは+00:00オフセットを持つ絶対的な瞬間を表します。ライターでの暗黙の切り捨てを拒否し、入力を正規のISO-8601または明示的なエポックナノ秒値に正規化し、範囲、符号、および丸めを検証します。移行前に機能マトリックスを構築します。v3をサポートしていないリーダーには、新しい型を推測させるのではなく、互換性ビューまたは二重書き込みされたミリ秒カラムを使用させます。リプレイテスト、クロスsimpタイムゾーンテスト、および境界値テストで結果を検証します。
ステップバイステップの設計
1. 時間のセマンティクスを確立する
誕生日やビジネスの日付はローカルのカレンダー値です。ログ、取引、トレーススパンは通常、世界で唯一の瞬間を表し、timestamptz_nsを使用する必要があります。created_atという名前のフィールドはUTCであることを証明するものではなく、ローカルオフセットを暗黙的に破棄してはなりません。
2. 精度の境界を保持する
入力を解析し、9桁の小数部をすべて保持します。最初にJavaScriptのDateやミリ秒の整数を通過させないでください。シリアライズされた値と解析された値をラウンドトリップで比較し、ナノ秒コンポーネントが変更されないようにします。
stored_ns = parse(input)
assert format(parse(format(stored_ns))) == stored_ns3. タイムゾーンと外れ値を処理する
タイムゾーン対応の型には正規のオフセットが必要です。UTC表現を保存し、表示時にのみ変換します。1970年より前の負のエポック、うるう秒ポリシー、夏時間の境界、および実装範囲外の値をテストします。曖昧なローカル文字列を拒否するか、呼び出し元にタイムゾーンの提供を要求します。
4. 互換性マトリックスを構築する
カタログ、ライター、バッチリーダー、ストリーミングリーダー、およびBIエンジンを対象とします。それぞれがv3を認識するか、ナノ秒を保持するか、未知の型で失敗するか無視するかを記録します。ライブラリのバージョンだけで動作を推測しないでください。すべてのエンジンで最小限の読み書きテーブルを実行します。
5. 移行とフォールバックを計画する
両方のナノ秒型を隔離されたテーブルに書き込み、実際のサンプルをリプレイします。古いリーダーがv3をサポートできない場合は、精度の免責事項を付記した明示的なミリ秒派生カラムを公開します。決してナノ秒データであるかのように見せかけてはなりません。二重書き込み、等価性チェック、エンジンごとの切り替えを使用し、古いテーブルまたはカラムへの切り戻し手段を確保します。
6. データ品質を監視する
切り捨て、解析エラー、欠落したタイムゾーン、負の値の比率、およびエンジン間のラウンドトリップの差異を追跡します。生のイベント、Icebergファイル、およびクエリ結果をサンプリングします。スキーマバージョン、ライターバージョン、およびタイムゾーンポリシーを監査メタデータに記録します。
模範解答
まず、その値が絶対的な瞬間であるかどうかを確認します。絶対的なイベントにはtimestamptz_nsを使用し、ローカルのカレンダー値にはtimestamp_nsを使用します。ライターはナノ秒表現をエンドツーエンドで保持し、ミリ秒APIを拒否し、9桁のラウンドトリップ、負のエポック、夏時間の境界、および範囲制限をテストします。移行前にv3機能マトリックスを構築します。古いリーダーには明示的なミリ秒派生カラムまたは互換性ビューを使用させ、暗黙の切り捨ては決して行いません。二重書き込みを行い、エンジンごとに切り替え、損失と乖離を監視し、古いテーブルまたはカラムへの切り戻しを維持します。
よくある間違い
- 両方の型をUTCとして扱う → ローカルカレンダーの意味が変わってしまう → まずセマンティクスを確立する。
- v3に書き込む前にミリ秒に変換する → 精度がすでに失われている → ナノ秒をエンドツーエンドで保持する。
+08:00オフセットを削除する → 異なる瞬間がマージされてしまう → UTCに正規化してからローカルで表示する。- 書き込み成功のみをテストする → 古いリーダーが失敗または切り捨てる可能性がある → マトリックス全体とリプレイをテストする。
- バージョン番号を信用する → フォーマットのサポートが異なる可能性がある → 最小限のクロスエンジン読み書きを実行する。
フォローアップの質問と回答
timestamp_nsをtimestamptz_nsに置き換えることはできますか?
いいえ。前者はタイムゾーンを持たず、定義されたカレンダーセマンティクスに適合します。後者はオフセットを持つ瞬間を表現します。一方を他方に置き換えると、精度だけでなくビジネス上の意味も変わります。
古いエンジンがv3テーブルを読み取れない場合はどうしますか?
未知の型を拒否するのか、それとも他のカラムを読み取ることができるのかを判断します。本番環境では、明示的に精度を落とした互換性ビューまたは二重書き込みされたミリ秒カラムを使用し、古いエンジンに推測させないようにします。
ナノ秒の順序付けは因果関係の順序付けと同じですか?
いいえ。異なるマシンのクロックの値にはスキューが発生する可能性があります。順序付けには依然としてイベントID、ソースシーケンス番号、または論理クロックが必要です。タイムスタンプは観測値にすぎません。