> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
Bu teknik özellik, TrustGraph'e büyük belgelerin yüklenmesi sırasında ortaya çıkan ölçeklenebilirlik ve kullanıcı deneyimi sorunlarını ele almaktadır. Mevcut mimari, belge yüklemeyi tek bir atomik işlem olarak ele almaktadır, bu da boru hattının çeşitli noktalarında bellek yüklenmesine neden olmakta ve kullanıcılara herhangi bir geri bildirim veya kurtarma seçeneği sunmamaktadır.
Bu uygulama, aşağıdaki kullanım senaryolarına yöneliktir:
1.**Büyük PDF İşleme**: Belleği tüketmeden yüzlerce megabayt boyutunda PDF dosyalarını yükleyin ve işleyin.
2.**Devam Eden Yüklemeler**: Kesintiye uğrayan yüklemelerin, baştan başlamak yerine, durdurulduğu yerden devam etmesini sağlayın.
3.**İlerleme Geri Bildirimi**: Kullanıcılara yükleme ve işleme sürecinin gerçek zamanlı görünürlüğünü sağlayın.
4.**Bellek Verimli İşleme**: Belgeleri, tüm dosyaları bellekte tutmadan, akış halinde işleyin.
## Hedefler
**Artımlı Yükleme**: REST ve WebSocket üzerinden parçalı belge yüklemeyi destekleyin.
**Devam Eden Aktarımlar**: Kesintiye uğrayan yüklemelerden kurtarmayı sağlayın.
**İlerleme Görünürlüğü**: İstemcilere yükleme/işleme sürecinin ilerleme durumunu geri bildirin.
**Bellek Verimliliği**: Boru hattının tamamında tam belge tamponlamayı ortadan kaldırın.
**Geriye Dönük Uyumluluk**: Mevcut, küçük belge iş akışlarının değişmeden devam etmesini sağlayın.
**Akış İşleme**: PDF kod çözme ve metin parçalama işlemleri, akışlar üzerinde gerçekleştirilir.
## Arka Plan
### Mevcut Mimari
Belge gönderme işlemi, aşağıdaki yolu izlemektedir:
1.**İstemci**, belgeyi REST (`POST /api/v1/librarian`) veya WebSocket üzerinden gönderir.
2.**API Ağ Geçidi**, base64 ile kodlanmış belge içeriği içeren eksiksiz isteği alır.
3.**LibrarianRequestor**, isteği Pulsar mesajına dönüştürür.
API şeması: `trustgraph-base/trustgraph/schema/services/library.py`
### Mevcut Sınırlamalar
Mevcut tasarımın, çeşitli birikimli bellek ve kullanıcı deneyimi sorunları bulunmaktadır:
1.**Atomik Yükleme İşlemi**: Tüm belge,
tek bir istekte iletilmelidir. Büyük belgeler, bağlantı başarısız olursa geri alma mekanizması olmadan, ilerleme göstergesi olmayan uzun süreli istekler gerektirir.
2.**API Tasarımı**: Hem REST hem de WebSocket API'leri,
tüm belgeyi tek bir mesajda bekler. Şema (`LibrarianRequest`), tüm base64 ile kodlanmış belgeyi içeren tek bir `content`
alanına sahiptir.
3.**Kütüphaneci Belleği**: Kütüphaneci hizmeti, belgeyi S3'e yüklemeden önce tüm belgeyi belleğe aktarır. 500MB'lık bir PDF için, bu, işlem belleğinde 500MB+'yi tutmak anlamına gelir.
500MB+ işlem belleğinde tutmak anlamına gelir.
4.**PDF Kod Çözücü Belleği**: İşleme başladığında, PDF kod çözücü, metni çıkarmak için tüm PDF'yi belleğe yükler. PyPDF ve benzeri kütüphaneler genellikle belgenin tamamına erişim gerektirir.
5.**Parçalayıcı Belleği**: Metin parçalayıcı, çıkarılan tamamlanmış metni alır ve parçalar oluştururken bunu bellekte tutar.
**Bellek Kullanımı Örneği** (500MB PDF):
Gateway: ~700MB (base64 kodlama ek yükü)
Librarian: ~500MB (çözülmüş baytlar)
PDF Çözücü: ~500MB + çıkarma arabellekleri
Parçalayıcı: çıkarılan metin (değişken, potansiyel olarak 100MB+)
Tek bir büyük belge için toplam maksimum bellek kullanımı 2GB'ı aşabilir.
## Teknik Tasarım
### Tasarım İlkeleri
1.**API Arayüzü**: Tüm istemci etkileşimi, librarian API'si üzerinden gerçekleşir. İstemciler,
temelindeki S3/Garage depolamaya doğrudan erişemez veya bu depolama hakkında bilgi sahibi değildir.
2.**S3 Çoklu Parça Yükleme**: Temelde standart S3 çoklu parça yükleme özelliğini kullanın.
Bu, S3 uyumlu sistemlerde (AWS S3, MinIO, Garage,
Ceph, DigitalOcean Spaces, Backblaze B2, vb.) yaygın olarak desteklenir ve taşınabilirliği sağlar.
3.**Atomik Tamamlama**: S3 çoklu parça yüklemeleri doğası gereği atomiktir; yüklenen
parçalar, `CompleteMultipartUpload` çağrılana kadar görünmez. Geçici
dosyalar veya yeniden adlandırma işlemleri gerekmez.
4.**Takip Edilebilir Durum**: Yükleme oturumları Cassandra'da takip edilir, bu da
tamamlanmamış yüklemeler hakkında görünürlük sağlar ve devam ettirme özelliğini etkinleştirir.
1. Oturumu kontrol eder, tüm parçaların alındığından emin olur.
2. Parça etiketleriyle birlikte S3'ü `CompleteMultipartUpload` ile çağırır (S3 parçaları dahili olarak birleştirir - kütüphaneci için bellek maliyeti sıfırdır).
3. Cassandra'da, meta veriler ve nesne referansı ile birlikte bir belge kaydı oluşturur.
4. Yükleme oturumu kaydını siler.
5. Belge kimliğini müşteriye döndürür.
#### `abort-upload`
Devam eden bir yüklemeyi iptal et.
İstek:
```json
{
"operation": "abort-upload",
"upload-id": "upload-abc-123"
}
```
Kütüphaneci:
1. Parçaları temizlemek için S3 `AbortMultipartUpload`'ı çağırır.
2. Oturum kaydını Cassandra'dan siler.
#### `get-upload-status`
Bir yüklemenin durumunu sorgula (devam ettirme özelliği için).
**S3 minimumu**: Parça başına 5 MB (son parça hariç)
**S3 maksimumu**: Bir yükleme başına 10.000 parça
**Pratik varsayılan**: 5 MB'lık parçalar
500 MB'lık bir belge = 100 parça
5 GB'lık bir belge = 1.000 parça
**İlerleme hassasiyeti**: Daha küçük parçalar = daha hassas ilerleme güncellemeleri
**Ağ verimliliği**: Daha büyük parçalar = daha az sayıda istek
Parça boyutu, belirli sınırlar içinde (5 MB - 100 MB) istemci tarafından yapılandırılabilir.
### Belge İşleme: Akışlı Alma
Yükleme akışı, belgelerin depolamaya verimli bir şekilde aktarılmasını sağlar. İşleme akışı, belgelerin tamamını belleğe yüklemeden, belgelerin çıkarılmasını ve parçalara ayrılmasını sağlar.
#### Tasarım İlkesi: İçerik Değil, Tanımlayıcı
Şu anda, işleme başlatıldığında, belge içeriği Pulsar mesajları aracılığıyla akar. Bu, tüm belgelerin belleğe yüklenmesine neden olur. Bunun yerine:
Pulsar mesajları yalnızca **belge tanımlayıcısını** taşır
İşleyiciler, belge içeriğini doğrudan kütüphaneden alırlar
Alma işlemi, bir **geçici dosyaya akış şeklinde** gerçekleşir
Belgeye özgü ayrıştırma (PDF, metin vb.), bellek arabellekleri yerine dosyalarla çalışır
Bu, kütüphanenin belge yapısına bağımlı olmamasını sağlar. PDF ayrıştırma, metin
çıkarma ve diğer biçime özgü mantık, ilgili kodlayıcılarda kalır.
#### İşleme Akışı
```
Pulsar PDF Decoder Librarian S3
│ │ │ │
│── doc-id ───────────►│ │ │
│ (processing msg) │ │ │
│ │ │ │
│ │── stream-document ──────►│ │
│ │ (doc-id) │── GetObject ────►│
│ │ │ │
│ │◄── chunk ────────────────│◄── stream ───────│
│ │ (write to temp file) │ │
│ │◄── chunk ────────────────│◄── stream ───────│
│ │ (append to temp file) │ │
│ │ ⋮ │ ⋮ │
│ │◄── EOF ──────────────────│ │
│ │ │ │
│ │ ┌──────────────────────────┐ │
│ │ │ temp file on disk │ │
│ │ │ (memory stays bounded) │ │
│ │ └────────────┬─────────────┘ │
│ │ │ │
│ │ PDF library opens file │
│ │ extract page 1 text ──► chunker │
│ │ extract page 2 text ──► chunker │
│ │ ⋮ │
│ │ close file │
│ │ delete temp file │
```
#### Kütüphaneci Akış API'si
Bir akışlı belge alma işlemi ekleyin:
**`stream-document`**
İstek:
```json
{
"operation": "stream-document",
"document-id": "doc-123"
}
```
Yanıt: Akışlı ikili veri parçaları (tek bir yanıt değil).
REST API için, bu, `Transfer-Encoding: chunked` ile bir akışlı yanıt döndürür.
İç hizmetler arası iletişimler (işlemci ile kütüphaneci), şu şekilde olabilir:
İmza yoluyla doğrudan S3 akışı (eğer iç ağ izin veriyorsa)
Hizmet protokolü üzerinden parçalı yanıtlar
Özel bir akış uç noktası
Temel gereksinim: Veri, kütüphaneci tarafından asla tamamen tamponlanmadan, parçalar halinde akmalıdır.
#### PDF Kod Çözücü Değişiklikleri
**Mevcut uygulama** (bellek yoğun):
```python
def decode_pdf(document_content: bytes) -> str:
reader = PdfReader(BytesIO(document_content)) # full doc in memory
Hiçbir noktada, tam belge veya tam çıkarılmış metin bellekte tutulmaz.
#### Geçici Dosya Hususları
**Konum:** Sistem geçici dizinini kullanın (`/tmp` veya eşdeğeri).
Sanallaştırılmış dağıtımlar için, geçici dizinin yeterli alana sahip olduğundan ve mümkünse hızlı depolama üzerinde olduğundan emin olun.
**Temizleme:** Temizlemenin, istisnalar olsa bile, sağlanması için bağlam yöneticileri (`with tempfile...`) kullanın.
**Eşzamanlı işleme:** Her işleme görevi kendi geçici dosyasına sahiptir.
Paralel belge işleme arasında herhangi bir çakışma olmaz.
**Disk alanı:** Geçici dosyalar, kısa ömürlüdür (işlem süresi boyunca).
500MB'lık bir PDF için, işleme sırasında 500MB geçici alana ihtiyaç vardır. Disk alanı sınırlıysa, boyut sınırı yükleme sırasında uygulanabilir.
### Birlikte Çalışan İşlem Arayüzü: Alt Belgeler
PDF çıkarma ve metin belge işleme, aynı
aşağı akış hattına (parçalayıcı → gömüler → depolama) beslenmelidir. Bunu, tutarlı bir "ID'ye göre alma" arayüzüyle sağlamak için, çıkarılan metin blokları, "librarian"a alt belgeler olarak geri kaydedilir.
| `extracted` | Kaynak bir belgeden türetilmiş (örneğin, PDF sayfa metni) |
**Meta veri alanları:**
| Alan | Kaynak Belge | Çıkarılan Alt Belge |
|-------|-----------------|-----------------|
| `id` | kullanıcı tarafından sağlanan veya oluşturulan | oluşturulan (örneğin, `{parent-id}-page-{n}`) |
| `parent_id` | `NULL` | ana belge kimliği |
| `document_type` | `source` | `extracted` |
| `kind` | `application/pdf`, vb. | `text/plain` |
| `title` | kullanıcı tarafından sağlanan | oluşturulan (örneğin, "Rapor.pdf'nin 3. sayfası") |
| `user` | kimliği doğrulanmış kullanıcı | ana belge ile aynı |
#### Alt Belgeler için Kütüphaneci API'si
**Alt belgeler oluşturma** (içerik, pdf-extractor tarafından kullanılır):
```json
{
"operation": "add-child-document",
"parent-id": "doc-123",
"document-metadata": {
"id": "doc-123-page-1",
"kind": "text/plain",
"title": "Page 1"
},
"content": "<base64-encoded-text>"
}
```
Küçük boyutlu, çıkarılmış metinler için (tipik bir sayfa metni <100KB),tekseferlikyüklemekabuledilebilir.Çokbüyükmetinçıkarımlarıiçin,parçalıyüklemekullanılabilir.