GH GambleHub

Sayfalama ve imleçler

1) Neden paginasyon gereklidir

Pagination, istemci tarafından iletilen ve oluşturulan veri miktarını sınırlar, depolama/ağlar üzerindeki yükü azaltır ve koleksiyon boyunca "yürümek" için deterministik bir yol belirler. Gerçek sistemlerde, sayfalama sadece 'sayfa = 1 & limit = 50'değil, bir dizi protokol sözleşmesi ve tutarlılık değişmezidir.

Tipik hedefler:
  • İstek başına gecikme ve bellek kontrolü.
  • Bir veri kümesini değiştirirken kararlı gezinme (ekle/sil).
  • Bir yerden devam etme yeteneği (yeniden başlatma).
  • Önbelleğe alma ve önbelleğe alma (prefetch).
  • Kötüye kullanıma karşı koruma (hız sınırlaması, geri basınç).

2) Pagination modelleri

2. 1 OFSET/LIMIT (sayfalı)

Fikir: "N çizgilerini atla, M'yi geri ver".
Artıları: basitlik, hemen hemen her SQL/NoSQL ile uyumlu.

Eksileri:
  • Doğrusal bozulma: Büyük OFSET'ler tam tarama/atlama maliyetiyle sonuçlanır.
  • İstekler arasındaki eklemeler/silmeler sırasında kararsızlık ("float" ofsetleri).
  • Doğru "yenilenebilirlik" sağlamak zordur.
SQL örneği:
sql
SELECT
FROM orders
ORDER BY created_at DESC, id DESC
OFFSET 1000 LIMIT 50;

2. 2 İmleç/Keyset/Arama sayfası

Fikir: "K tuşuna bas. "İmleç, sıralanmış kümedeki konumdur.

Artıları:
  • O (1) dizine devam etmek için erişim.
  • Toplama değişiklikleri sırasında stabilite.
  • Derin "sayfalarda'en iyi gecikme.
Eksileri:
  • Kesinlikle tanımlanmış, benzersiz ve monoton sıralama anahtarlarına ihtiyacımız var.
  • Uygulaması ve hata ayıklaması daha zordur.
SQL örneği (ara):
sql
-- Resumption after steam (created_at, id) = (:last_ts,:last_id)
SELECT
FROM orders
WHERE (created_at, id) < (:last_ts,:last_id)
ORDER BY created_at DESC, id DESC
LIMIT 50;

2. 3 Devam belirteçleri

Fikir: sunucu, "konumun" kodlandığı opak bir belirteç döndürür (ve muhtemelen parçacıkların/filtrelerin durumu). Müşteri iç kısımları anlamıyor ve sadece bir sonraki sayfa için bir jeton döndürüyor.
Artıları: esneklik, API'yi bozmadan şemayı değiştirme yeteneği.
Eksileri: belirteç ömür boyu yönetimi, mevduat ile uyumluluk.

2. 4 Zaman ve mantık imleçleri

Zaman tabanlı: "T'ye kadar tüm kayıtlar", imleç - zaman damgası (yalnızca ek iş parçacıkları için uygundur).
Log-sequence/offset tabanlı: imleç - günlükte offset (Kafka offset, journal seq).
Global monotonik kimlikler: Kararlı arama için sıralanabilir anahtarlar olarak Snowflake/UUIDv7.

3) Kursların ve belirteçlerin tasarlanması

3. 1 İyi İmleç Özellikleri

Opak - İstemci formattan bağımsızdır.
Yazarlık/bütünlük: Sahteciliği/manipülasyonu önlemek için HMAC imzası.
Bağlam: sıralama, filtreler, şema sürümü, kiracı/parça içerir.
Ömür boyu: TTL ve indeksleri/erişim haklarını değiştirirken "tekrar oynatmama".
Boyut: URL için uygun kompakt (<= 1-2 KB).

3. 2 Token formatı

Önerilen yığın: JSON - sıkıştırma (zstd/deflate) - Base64URL - HMAC.

Payload yapısı (örnek):
json
{
"v": 3 ,//token version
"sort": ["created_at:desc","id:desc"],
"pos": {"created_at":"2025-10-30T12:34:56. 789Z","id":"987654321"},
"filters": {"user_id":"42","status":["paid","shipped"]},
"tenant": "eu-west-1",
"shards": [{"s ": "a, "" hi":"..."}] ,//optional: cross-shard context
"issued_at": "2025-10-31T14:00:00Z",
"ttl_sec": 3600
}

'mac = HMAC (gizli, yük)' üste eklenir ve her şey bir dize belirtecine kodlanır.

3. 3 Güvenlik

İşaret (HMAC/SHA-256).
İsteğe bağlı olarak (AES-GCM) hassas değerlerin (PII) varlığında şifreleyin.
Sunucu doğrulama: sürüm, TTL, kullanıcı otoritesi (RBAC/ABAC).

4) Tutarlılık ve değişmezler

4. 1 Kararlı sıralama

Tam determinizm kullanın: 'ORDER BY ts DESC, id DESC'.
Sıralama anahtarı benzersiz olmalıdır (tiebreaker olarak'id 'ekleyin).
Dizin, kaplayan dizin ile eşleşmelidir.

4. 2 Anlık görüntüler ve izolasyon

Jumbo olmayan sayfalar için, okuma tutarlı anlık görüntü (MVCC/txid) kullanın.
Anlık görüntü pratik değilse (pahalı/çok fazla veri), bir sözleşme formüle edin: "imleç, konumdan kesinlikle önce öğeleri döndürür. Bu haber kaynakları için doğaldır.

4. 3 Sayfalar arasındaki eklemeler/silmeler

Seek-model "kopyaları/eksiklikleri'en aza indirir.
Belge silme/değiştirme davranışı: Sayfalar arasında nadir "deliklere" izin verilir, ancak "zamanda geri" izin verilmez.

5) İndeksleme ve kimlik şemaları

Bileşik indeksler kesinlikle sıralama düzenindedir: '(created_at DESC, id DESC)'.
Monoton kimlikler: Zaman içinde düzen Snowflake/UUIDv7 - aramayı hızlandırın.
Kısayol tuşları: shard-key (örneğin, 'tenant _ id', 'region') ile dağıtın ve shard içinde sıralayın.
Kimlik üreteçleri: NTP sıçramaları sırasında çarpışmalar ve "saat eğriltme" - zaman senkronizasyonu, "regresyon" önlemek.

6) Çapraz parça sayfalama

6. 1 Şemalar

Scatter-Gather: tüm parçalara paralel istekler, yerel arama kursları, sonra toplayıcı üzerinde k-way birleştirme.
Per-Shard Cursors: Belirteç, her parça üzerinde konumlar içerir.
Sınırlı fan çıkışı Adım başına parça sayısını sınırlayın (oran sınırlaması/zaman aşımı bütçesi).

6. Çoklu parça için 2 Jeton

Mağaza dizisi '{shard _ id, last_pos}'. Bir sonraki adımda, her aktif parça için devam edin ve küresel olarak sıralanmış sayfayı vererek tekrar tutun.

7) Protokol sözleşmeleri

7. 1 REST

İstek:

GET /v1/orders? limit=50&cursor=eyJ2IjoiMyIsInNvcnQiOiJjcmVh... (opaque)
Cevap:
json
{
"items": [ /... / ],
"page": {
"limit": 50,
"next_cursor": "eyJ2IjozLCJwb3MiOiJjcmVh...==",
"has_more": true
}
}
Öneriler:
  • Üst sınırı olan 'limit' (örneğin, max = 200).
  • 'next _ cursor' eksik ise 'has _ more = false'.
  • GET idempotence, 'next _ cursor' olmadan verilen yanıtların hesaplanabilirliği (sabit filtreler ve anlık görüntü içeren ilk sayfa).

7. 2 GraphQL (Röle yaklaşımı)

Tipik 'bağlantı' sözleşmesi:
graphql type Query {
orders(first: Int, after: String, filter: OrderFilter): OrderConnection!
}

type OrderConnection {
edges: [OrderEdge!]!
pageInfo: PageInfo!
}

type OrderEdge {
node: Order!
cursor: String! // opaque
}

type PageInfo {
hasNextPage: Boolean!
endCursor: String
}

'crossor' opak ve imzalı olmalı; HMAC olmadan "ham Base64 (id)" kullanmayın.

7. 3 gRPC

'Page _ size've' page _ token 'kullanın:
proto message ListOrdersRequest {
string filter = 1;
int32 page_size = 2;
string page_token = 3; // opaque
}

message ListOrdersResponse {
repeated Order items = 1;
string next_page_token = 2; // opaque bool has_more = 3;
}

7. 4 Konu ve WebSockets

Sürekli bantlar için: imleç "son görülen ofset/ts'olarak.

Yeniden bağlanma sırasında 'resume _ from' desteği:
json
{ "action":"subscribe", "topic":"orders", "resume_from":"2025-10-31T12:00:00Z#987654321" }

8) Önbelleğe alma, Ön yükleme, CDN

Sabit filtreli ilk sayfa için ETag/If-None-Match.
Genel listeler için kısa bir TTL (örneğin, 5-30 s) ile önbellek kontrolü.
Prefetch: return 'next _ cursor've ipuçları (' Link: rel = "next" '), istemci bir sonraki sayfayı önceden yükleyebilir.
Varyasyonlar: Önbellek kısmının anahtarı olarak 'filter/sort/locale/tenant' seçeneğini düşünün.

9) Yük yönetimi ve sınırlandırma

Üst sınır 'limit', örn. 200.
Sunucu tarafı geri baskı: istek süresi> bütçe ise, yanıttaki 'sınırı' azaltın (ve istemciye gerçek sayfa boyutunu açıkça söyleyin).
Kullanıcı/belirteç/kiracı başına oran sınırları.
Zaman aşımı/Yeniden deneme: üstel duraklatma, idempotent tekrarlanan istekleri.

10) UX yönleri

Numaralandırmaya karşı kaydırma: sonsuz kaydırma - imleçler; Sayı sayfaları - ofset (ancak verileri güncellerken yanlışlığı açıklayın).
Yerine dön düğmesi: İstemci imleci yığınını saklayın.
Boş sayfalar: 'Has _ more = false', Diğer düğmesini gösterme.
Kararlı sınırlar: Tam 'toplam'ı yalnızca ucuzsa gösterin (aksi takdirde yaklaşık bir' yaklaşım _ toplam ').

11) Test ve kenar durumları

Denetim listeleri:
  • Kararlı sıralama: Aynı't'lere sahip öğeler "göz kırpmaz".
  • Ekler/Siler - Kopyalar sayfa kesişiminde görünmez.
  • Sayfalar arasındaki filtreleri değiştirin: Belirteç eski/uyumsuz olarak reddedilmelidir.
  • Token TTL: Geçerlilik süresi dolduktan sonra geçerli hata.
  • Büyük derinlik: Gecikme doğrusal olarak büyümez.
  • Multishard: doğru birleştirme sırası, açlık yokluğu "yavaş" parçalar.
Özellik tabanlı test örneği (sözde kod):
python
Generate N entries with random inserts between calls
Verify that all pages are merged = = whole ordered fetch

12) Gözlemlenebilirlik ve SLO

Metrikler:
  • Sayfa uzunluğuna göre 'list _ request _ latency _ ms' (P50/P95/P99).
  • 'search _ index _ hit _ ratio' (örten indeks tarafından bırakılan isteklerin oranı).
  • 'next _ cursor _ invalid _ rate' (doğrulama/TTL/imza hataları).
  • 'merge _ fanout' (sayfa başına dahil olan parça sayısı).
  • 'duplicates _ on _ boundary've' gaps _ on _ boundary '(istemci telemetrisinde algılama).
Günlükler/izleme:
  • Günlüklerdeki 'cursor _ id', maske yükünü ilişkilendirin.
  • Etiket aralıkları: 'page _ size', 'source _ shards', 'db _ index _ used'.
SLO örneği:
  • Kullanılabilirlik: 99. 'Liste' yöntemlerinde %9.
  • Gecikme: Yerel bir şarjda 'page _ size <= 50' için <200 ms P95.
  • Belirteç hatası: <0. Toplam çağrı sayısının %1'i.

13) Geçişler ve birlikte çalışabilirlik

Belirteçte 'v'yi etkinleştirin ve N haftalarının eski sürümlerini destekleyin.
Sıralama tuşlarını değiştirirken - imleç olmadan yeni bir liste yapmak için bir istemle "yumuşak'bir hata '409 Çakışma' gönderin.
Felaket durumu (tüm belirteçlerin kükremesi): 'signing _ key _ id' seçeneğini değiştirin ve eskileri reddedin.

14) Uygulama örnekleri

14. 1 Belirteç üretimi (pseudocode)

python payload = json. dumps({...}). encode()
compressed = zlib. compress(payload)
mac = hmac_sha256(signing_key, compressed)
token = base64url_encode(mac + compressed)

14. 2 Belirteç doğrulama

python raw = base64url_decode(token)
mac, compressed = raw[:32], raw[32:]
assert mac == hmac_sha256(signing_key, compressed)
payload = json. loads(zlib. decompress(compressed))
assert now() - payload["issued_at"] < payload["ttl_sec"]
assert payload["filters"] == req. filters

14. 3 Bileşik anahtarla sorgu isteyin

sql
-- Page # 1
SELECT FROM feed
WHERE tenant_id =:t
ORDER BY ts DESC, id DESC
LIMIT:limit;

-- Next pages, continued after (ts0, id0)
SELECT FROM feed
WHERE tenant_id =:t
AND (ts <:ts0 OR (ts =:ts0 AND id <:id0))
ORDER BY ts DESC, id DESC
LIMIT:limit;

15) Güvenlik ve uyumluluk

PII'nin türetilebileceği belirteçlere ham alanlar dahil etmeyin.
TTL'yi imzalayın ve sınırlayın.
Belirteçleri kullanıcılar arasında dayanılmaz hale getirmeye çalışın (yükte 'alt/kiracı/roller' yazın ve doğrulama sırasında kontrol edin).
Sadece belirteç hash'lerini kaydedin.

16) Sık hatalar ve anti-desenler

İmleç olarak Base64 (id): kolay taklit etmek/almak, sıralamayı değiştirirken sözleşmeyi bozar.
Tie-breaker yok: 'ORDER BY ts DESC''id 'olmadan - kopyalar/sıçramalar.
Belirteci geçersiz kılmadan sayfalar arasındaki filtreleri değiştirin.
Derin ofset: Yavaş ve tahmin edilemez.
Sürüm ve TTL olmadan belirteçler.

17) Mini kontrol listesi uygulaması

1. Sıralamayı tanımlayın ve benzersiz bir tie-breaker ekleyin.
2. Bu sipariş için bir genişleme dizini oluşturun.
3. Model seçin: ara + opak belirteç.
4. Belirteç imzalama (ve gerekirse şifreleme) uygulayın.
5. TTL'yi ve sürümleri bırakın.
6. Formüle ve belge 'has _ more', 'next _ cursor' sözleşmeleri.
7. Bir çapraz parça şeması (gerekirse) ve k-yolu birleştirme düşünün.
8. Metrikler, uyarılar ve SLO'lar ekleyin.
9. Özellik tabanlı sayfa kenarlıklarını testlerle kaplayın.
10. Belirteçler için göç stratejisini açıklayın.

18) Bir yaklaşım seçmek için kısa öneriler

"Sayfa numarası've yaklaşık toplamın önemli olduğu dizinler/aramalar: 'OFSET/LIMIT' + önbellek diyelim; Bu toplam yaklaşık rapor.
Akışlar, analizler, derin listeler, yüksek RPS: yalnızca imleç/arama.
Shardy/dağıtılmış koleksiyonlar: parça başına imleçler + birleştirme belirteci.
Threads/CDC: özgeçmiş ile ofset/ts olarak imleçler.

19) API sözleşmesi örneği (özet)

'GET/v1/öğeleri? limit = 50 & imleç =... '

Cevap her zaman 'sayfa içerir. Limit ',' sayfası. has_more', isteğe bağlı 'sayfa. next_cursor'.
İmleç opak, imzalı, TTL ile.
Sıralama deterministik 'ORDER BY created_at DESC, id DESC'dir.
Değişim davranışını ayarla-Öğeler imlece göre "geri gitmez".
Metrikler ve hatalar standartlaştırılmıştır: 'invalid _ cursor', 'expired _ cursor', 'mismatch _ filters'.

Bu makale, büyük verilerde bile hızlı, öngörülebilir ve güvenli, dağınık ve aktif olarak değişen kayıt kümeleri tasarlamak için mimari ilkeler ve hazır desenler sunmaktadır.

Contact

Bizimle iletişime geçin

Her türlü soru veya destek için bize ulaşın.Size yardımcı olmaya her zaman hazırız!

Entegrasyona başla

Email — zorunlu. Telegram veya WhatsApp — isteğe bağlı.

Adınız zorunlu değil
Email zorunlu değil
Konu zorunlu değil
Mesaj zorunlu değil
Telegram zorunlu değil
@
Telegram belirtirseniz, Email’e ek olarak oradan da yanıt veririz.
WhatsApp zorunlu değil
Format: +ülke kodu ve numara (örneğin, +90XXXXXXXXX).

Butona tıklayarak veri işlemenize onay vermiş olursunuz.