trustgraph/docs/tech-specs/multi-tenant-support.ar.md
Alex Jenkins 8954fa3ad7 Feat: TrustGraph i18n & Documentation Translation Updates (#781)
Native CLI i18n: The TrustGraph CLI has built-in translation support
that dynamically loads language strings. You can test and use
different languages by simply passing the --lang flag (e.g., --lang
es for Spanish, --lang ru for Russian) or by configuring your
environment's LANG variable.

Automated Docs Translations: This PR introduces autonomously
translated Markdown documentation into several target languages,
including Spanish, Swahili, Portuguese, Turkish, Hindi, Hebrew,
Arabic, Simplified Chinese, and Russian.
2026-04-14 12:08:32 +01:00

36 KiB

layout title parent
default المواصفات الفنية: دعم البيئات متعددة المستأجرين Arabic (Beta)

المواصفات الفنية: دعم البيئات متعددة المستأجرين

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.

نظرة عامة

تمكين عمليات النشر متعددة المستأجرين عن طريق إصلاح عدم تطابق أسماء المعلمات التي تمنع تخصيص قائمة الانتظار وإضافة معلمات مساحة مفاتيح Cassandra.

سياق البنية

حل قائمة الانتظار القائم على التدفق

يستخدم نظام TrustGraph بنية قائمة انتظار قائمة على التدفق لحل ديناميكي لقوائم الانتظار، والتي تدعم بشكل طبيعي البيئات متعددة المستأجرين:

يتم تخزين تعريفات التدفق في Cassandra وتحدد أسماء قوائم الانتظار عبر تعريفات الواجهة. تستخدم أسماء قوائم الانتظار قوالب مع متغيرات {id} يتم استبدالها بمعرفات مثيلات التدفق. تقوم الخدمات بحل قوائم الانتظار ديناميكيًا عن طريق البحث عن تكوينات التدفق في وقت الطلب. يمكن لكل مستأجر أن يكون لديه تدفقات فريدة بأسماء قوائم انتظار مختلفة، مما يوفر عزلًا.

مثال لتعريف واجهة التدفق:

{
  "interfaces": {
    "triples-store": "persistent://tg/flow/triples-store:{id}",
    "graph-embeddings-store": "persistent://tg/flow/graph-embeddings-store:{id}"
  }
}

عندما يبدأ المستأجر أ سير العمل tenant-a-prod ويبدأ المستأجر ب سير العمل tenant-b-prod، فإنهم يحصلون تلقائيًا على قوائم انتظار معزولة: persistent://tg/flow/triples-store:tenant-a-prod persistent://tg/flow/triples-store:tenant-b-prod

الخدمات المصممة بشكل صحيح لدعم تعدد المستأجرين: إدارة المعرفة (الأساسيات) - تحل ديناميكيًا قوائم الانتظار من تكوين سير العمل الذي يتم تمريره في الطلبات.

الخدمات التي تحتاج إلى إصلاحات: 🔴 خدمة التكوين - عدم تطابق اسم المعلمة يمنع تخصيص قائمة الانتظار. 🔴 خدمة أمين المكتبة - مواضيع إدارة التخزين المبرمجة بشكل ثابت (موضحة أدناه). 🔴 جميع الخدمات - لا يمكن تخصيص مساحة مفتاح Cassandra.

بيان المشكلة

المشكلة رقم 1: عدم تطابق اسم المعلمة في AsyncProcessor

يعرف سطر الأوامر: --config-queue (تسمية غير واضحة) يقوم Argparse بتحويلها إلى: config_queue (في قاموس المعلمات) يبحث الكود عن: config_push_queue النتيجة: يتم تجاهل المعلمة، وتعود إلى القيمة الافتراضية persistent://tg/config/config. التأثير: يؤثر على أكثر من 32 خدمة ترث من AsyncProcessor. يمنع: لا يمكن لنشر تعدد المستأجرين استخدام قوائم انتظار تكوين خاصة بالمستأجر. الحل: إعادة تسمية معلمة سطر الأوامر إلى --config-push-queue من أجل الوضوح (تغيير كاسر مقبول نظرًا لأن الميزة معطلة حاليًا).

المشكلة رقم 2: عدم تطابق اسم المعلمة في خدمة التكوين

يعرف سطر الأوامر: --push-queue (تسمية غامضة) يقوم Argparse بتحويلها إلى: push_queue (في قاموس المعلمات) يبحث الكود عن: config_push_queue النتيجة: يتم تجاهل المعلمة. التأثير: لا يمكن لخدمة التكوين استخدام قائمة انتظار دفع مخصصة. الحل: إعادة تسمية معلمة سطر الأوامر إلى --config-push-queue من أجل الاتساق والوضوح (تغيير كاسر مقبول).

المشكلة رقم 3: مساحة مفتاح Cassandra مبرمجة بشكل ثابت

الحالي: مساحة المفتاح مبرمجة بشكل ثابت كـ "config"، "knowledge"، "librarian" في خدمات مختلفة. النتيجة: لا يمكن تخصيص مساحة المفتاح لنشر تعدد المستأجرين. التأثير: خدمات التكوين والأساسيات وأمين المكتبة. يمنع: لا يمكن لعدة مستأجرين استخدام مساحات مفاتيح Cassandra منفصلة.

المشكلة رقم 4: بنية إدارة المجموعات مكتمل

السابق: تم تخزين المجموعات في مساحة مفاتيح Cassandra الخاصة بأمين المكتبة عبر جدول مجموعات منفصل. السابق: استخدم أمين المكتبة 4 مواضيع إدارة تخزين مبرمجة بشكل ثابت لتنسيق إنشاء/حذف المجموعة: vector_storage_management_topic object_storage_management_topic triples_storage_management_topic storage_management_response_topic المشاكل (تم حلها): لا يمكن تخصيص المواضيع المبرمجة بشكل ثابت لنشر تعدد المستأجرين. تنسيق غير متزامن معقد بين أمين المكتبة و 4+ خدمات تخزين. جدول منفصل وبنية تحتية لإدارة. قوائم انتظار طلب/استجابة غير دائمة للعمليات الهامة. الحل المنفذ: تم نقل المجموعات إلى تخزين خدمة التكوين، واستخدام دفع التكوين للتوزيع. الحالة: تم نقل جميع خلفيات التخزين إلى النمط CollectionConfigHandler.

الحل

تعالج هذه المواصفات المشكلات رقم 1 و 2 و 3 و 4.

الجزء الأول: إصلاح عدم تطابق اسم المعلمة

التغيير 1: فئة AsyncProcessor الأساسية - إعادة تسمية معلمة سطر الأوامر

الملف: trustgraph-base/trustgraph/base/async_processor.py السطر: 260-264

الحالي:

parser.add_argument(
    '--config-queue',
    default=default_config_queue,
    help=f'Config push queue {default_config_queue}',
)

ثابت:

parser.add_argument(
    '--config-push-queue',
    default=default_config_queue,
    help=f'Config push queue (default: {default_config_queue})',
)

السبب: تسمية أوضح وأكثر تفصيلاً. تتطابق مع اسم المتغير الداخلي config_push_queue. التغيير قد يكون مؤثراً، ولكن هذا مقبول لأن الميزة غير فعالة حاليًا. لا حاجة لتغيير أي كود في params.get() - فهو يبحث بالفعل عن الاسم الصحيح.

التغيير الثاني: خدمة التكوين - إعادة تسمية معلمة سطر الأوامر

الملف: trustgraph-flow/trustgraph/config/service/service.py السطر: 276-279

الحالي:

parser.add_argument(
    '--push-queue',
    default=default_config_push_queue,
    help=f'Config push queue (default: {default_config_push_queue})'
)

ثابت:

parser.add_argument(
    '--config-push-queue',
    default=default_config_push_queue,
    help=f'Config push queue (default: {default_config_push_queue})'
)

السبب: تسمية أوضح - "config-push-queue" أكثر وضوحًا من مجرد "push-queue". يتطابق مع اسم المتغير الداخلي config_push_queue. متسق مع معلمة --config-push-queue الخاصة بـ AsyncProcessor. التغيير غير المتوافق مقبول نظرًا لأن الميزة غير وظيفية حاليًا. لا حاجة لتغيير التعليمات البرمجية في params.get() - فهو يبحث بالفعل عن الاسم الصحيح.

الجزء الثاني: إضافة معلمات مساحة مفاتيح Cassandra

التغيير الثالث: إضافة معلمة مساحة المفاتيح إلى وحدة cassandra_config

الملف: trustgraph-base/trustgraph/base/cassandra_config.py

إضافة وسيط سطر الأوامر (في دالة add_cassandra_args()):

parser.add_argument(
    '--cassandra-keyspace',
    default=None,
    help='Cassandra keyspace (default: service-specific)'
)

إضافة دعم لمتغيرات البيئة (في الدالة resolve_cassandra_config()):

keyspace = params.get(
    "cassandra_keyspace",
    os.environ.get("CASSANDRA_KEYSPACE")
)

تحديث قيمة الإرجاع لـ resolve_cassandra_config(): حاليًا، تُرجع: (hosts, username, password) التغيير إلى إرجاع: (hosts, username, password, keyspace)

السبب: يتوافق مع نمط تكوين Cassandra الحالي متاح لجميع الخدمات عبر add_cassandra_args() يدعم كل من تكوين سطر الأوامر ومتغيرات البيئة

التغيير الرابع: خدمة التكوين - استخدام مفاتيح مساحة المفاتيح المعلمة

الملف: trustgraph-flow/trustgraph/config/service/service.py

السطر 30 - إزالة اسم مساحة المفاتيح الثابت:

# DELETE THIS LINE:
keyspace = "config"

السطور من 69 إلى 73 - تحديث آلية حل مشاكل إعدادات كاساندرا:

الحالي:

cassandra_host, cassandra_username, cassandra_password = \
    resolve_cassandra_config(params)

ثابت:

cassandra_host, cassandra_username, cassandra_password, keyspace = \
    resolve_cassandra_config(params, default_keyspace="config")

السبب: يحافظ على التوافق مع الإصدارات السابقة باستخدام "config" كإعداد افتراضي. يسمح بالتجاوز عبر --cassandra-keyspace أو CASSANDRA_KEYSPACE.

التغيير 5: الخدمات الأساسية/خدمة المعرفة - استخدام مفاتيح مساحة معلمات.

الملف: trustgraph-flow/trustgraph/cores/service.py

السطر 37 - إزالة مفتاح مساحة مُبرمج بشكل ثابت:

# DELETE THIS LINE:
keyspace = "knowledge"

تحديث آلية حل إعدادات كاساندرا (في نفس الموقع مثل خدمة الإعدادات):

cassandra_host, cassandra_username, cassandra_password, keyspace = \
    resolve_cassandra_config(params, default_keyspace="knowledge")

التغيير 6: خدمة أمين المكتبة - استخدام مفاتيح مساحة معلمات.

الملف: trustgraph-flow/trustgraph/librarian/service.py

السطر 51 - إزالة اسم مساحة المفاتيح المبرمج بشكل ثابت:

# DELETE THIS LINE:
keyspace = "librarian"

تحديث آلية حل إعدادات Cassandra (في نفس الموقع مثل خدمة الإعدادات):

cassandra_host, cassandra_username, cassandra_password, keyspace = \
    resolve_cassandra_config(params, default_keyspace="librarian")

الجزء الثالث: ترحيل إدارة المجموعات إلى خدمة التكوين

نظرة عامة

ترحيل المجموعات من مساحة مفاتيح Cassandra librarian إلى تخزين خدمة التكوين. هذا يلغي مواضيع إدارة التخزين المضمنة ويبسط البنية باستخدام آلية دفع التكوين الحالية للتوزيع.

البنية الحالية

API Request → Gateway → Librarian Service
                            ↓
                    CollectionManager
                            ↓
                    Cassandra Collections Table (librarian keyspace)
                            ↓
                    Broadcast to 4 Storage Management Topics (hardcoded)
                            ↓
        Wait for 4+ Storage Service Responses
                            ↓
                    Response to Gateway

العمارة الجديدة

API Request → Gateway → Librarian Service
                            ↓
                    CollectionManager
                            ↓
                    Config Service API (put/delete/getvalues)
                            ↓
                    Cassandra Config Table (class='collections', key='user:collection')
                            ↓
                    Config Push (to all subscribers on config-push-queue)
                            ↓
        All Storage Services receive config update independently

التغيير 7: مدير المجموعة - استخدام واجهة برمجة تطبيقات خدمة التكوين

الملف: trustgraph-flow/trustgraph/librarian/collection_manager.py

إزالة: استخدام LibraryTableStore (الأسطر 33، 40-41) تهيئة منتجي إدارة التخزين (الأسطر 86-140) طريقة on_storage_response (الأسطر 400-430) تتبع pending_deletions (الأسطر 57، 90-96، والاستخدام في جميع أنحاء البرنامج)

إضافة: عميل خدمة التكوين لإجراء مكالمات واجهة برمجة التطبيقات (نمط الطلب/الاستجابة)

إعداد عميل التكوين:

# In __init__, add config request/response producers/consumers
from trustgraph.schema.services.config import ConfigRequest, ConfigResponse

# Producer for config requests
self.config_request_producer = Producer(
    client=pulsar_client,
    topic=config_request_queue,
    schema=ConfigRequest,
)

# Consumer for config responses (with correlation ID)
self.config_response_consumer = Consumer(
    taskgroup=taskgroup,
    client=pulsar_client,
    flow=None,
    topic=config_response_queue,
    subscriber=f"{id}-config",
    schema=ConfigResponse,
    handler=self.on_config_response,
)

# Tracking for pending config requests
self.pending_config_requests = {}  # request_id -> asyncio.Event

تعديل list_collections (الأسطر من 145 إلى 180):

async def list_collections(self, user, tag_filter=None, limit=None):
    """List collections from config service"""
    # Send getvalues request to config service
    request = ConfigRequest(
        id=str(uuid.uuid4()),
        operation='getvalues',
        type='collections',
    )

    # Send request and wait for response
    response = await self.send_config_request(request)

    # Parse collections from response
    collections = []
    for key, value_json in response.values.items():
        if ":" in key:
            coll_user, collection = key.split(":", 1)
            if coll_user == user:
                metadata = json.loads(value_json)
                collections.append(CollectionMetadata(**metadata))

    # Apply tag filtering in-memory (as before)
    if tag_filter:
        collections = [c for c in collections if any(tag in c.tags for tag in tag_filter)]

    # Apply limit
    if limit:
        collections = collections[:limit]

    return collections

async def send_config_request(self, request):
    """Send config request and wait for response"""
    event = asyncio.Event()
    self.pending_config_requests[request.id] = event

    await self.config_request_producer.send(request)
    await event.wait()

    return self.pending_config_requests.pop(request.id + "_response")

async def on_config_response(self, message, consumer, flow):
    """Handle config response"""
    response = message.value()
    if response.id in self.pending_config_requests:
        self.pending_config_requests[response.id + "_response"] = response
        self.pending_config_requests[response.id].set()

تعديل update_collection (الأسطر من 182 إلى 312):

async def update_collection(self, user, collection, name, description, tags):
    """Update collection via config service"""
    # Create metadata
    metadata = CollectionMetadata(
        user=user,
        collection=collection,
        name=name,
        description=description,
        tags=tags,
    )

    # Send put request to config service
    request = ConfigRequest(
        id=str(uuid.uuid4()),
        operation='put',
        type='collections',
        key=f'{user}:{collection}',
        value=json.dumps(metadata.to_dict()),
    )

    response = await self.send_config_request(request)

    if response.error:
        raise RuntimeError(f"Config update failed: {response.error.message}")

    # Config service will trigger config push automatically
    # Storage services will receive update and create collections

تعديل delete_collection (الأسطر من 314 إلى 398):

async def delete_collection(self, user, collection):
    """Delete collection via config service"""
    # Send delete request to config service
    request = ConfigRequest(
        id=str(uuid.uuid4()),
        operation='delete',
        type='collections',
        key=f'{user}:{collection}',
    )

    response = await self.send_config_request(request)

    if response.error:
        raise RuntimeError(f"Config delete failed: {response.error.message}")

    # Config service will trigger config push automatically
    # Storage services will receive update and delete collections

تنسيق بيانات التعريف للمجموعة: يتم تخزينها في جدول التكوين كـ: class='collections', key='user:collection' القيمة هي بيانات تعريف المجموعة (CollectionMetadata) مُسلسلة بصيغة JSON (بدون حقول الطابع الزمني) الحقول: user، collection، name، description، tags مثال: class='collections', key='alice:my-docs', value='{"user":"alice","collection":"my-docs","name":"My Documents","description":"...","tags":["work"]}'

التغيير 8: خدمة أمين المكتبة - إزالة بنية إدارة التخزين

الملف: trustgraph-flow/trustgraph/librarian/service.py

إزالة: منتجي إدارة التخزين (الأسطر 173-190): vector_storage_management_producer object_storage_management_producer triples_storage_management_producer مستهلك الاستجابة للتخزين (الأسطر 192-201) معالج on_storage_response (الأسطر 467-473)

تعديل: تهيئة CollectionManager (الأسطر 215-224) - إزالة معلمات منتج التخزين

ملاحظة: تظل واجهة برمجة التطبيقات الخارجية للمجموعة دون تغيير: list-collections update-collection delete-collection

التغيير 9: إزالة جدول المجموعات من LibraryTableStore

الملف: trustgraph-flow/trustgraph/tables/library.py

حذف: عبارة CREATE لجدول المجموعات (الأسطر 114-127) عبارات Collections المُعدة (الأسطر 205-240) جميع طرق المجموعة (الأسطر 578-717): ensure_collection_exists list_collections update_collection delete_collection get_collection create_collection

السبب: يتم الآن تخزين المجموعات في جدول التكوين التغيير غير المتوافق مقبول - لا توجد حاجة لنقل البيانات يبسط خدمة أمين المكتبة بشكل كبير

التغيير 10: خدمات التخزين - إدارة المجموعة المستندة إلى التكوين تم

الحالة: تم ترحيل جميع خدمات التخزين الـ 11 لاستخدام CollectionConfigHandler.

الخدمات المتأثرة (11 خدمة إجمالاً): تضمينات المستندات: milvus, pinecone, qdrant تضمينات الرسم البياني: milvus, pinecone, qdrant تخزين الكائنات: cassandra تخزين الثلاثيات: cassandra, falkordb, memgraph, neo4j

الملفات: trustgraph-flow/trustgraph/storage/doc_embeddings/milvus/write.py trustgraph-flow/trustgraph/storage/doc_embeddings/pinecone/write.py trustgraph-flow/trustgraph/storage/doc_embeddings/qdrant/write.py trustgraph-flow/trustgraph/storage/graph_embeddings/milvus/write.py trustgraph-flow/trustgraph/storage/graph_embeddings/pinecone/write.py trustgraph-flow/trustgraph/storage/graph_embeddings/qdrant/write.py trustgraph-flow/trustgraph/storage/objects/cassandra/write.py trustgraph-flow/trustgraph/storage/triples/cassandra/write.py trustgraph-flow/trustgraph/storage/triples/falkordb/write.py trustgraph-flow/trustgraph/storage/triples/memgraph/write.py trustgraph-flow/trustgraph/storage/triples/neo4j/write.py

نمط التنفيذ (جميع الخدمات):

  1. سجل معالج التكوين في __init__:
# Add after AsyncProcessor initialization
self.register_config_handler(self.on_collection_config)
self.known_collections = set()  # Track (user, collection) tuples
  1. تنفيذ معالج التهيئة:
async def on_collection_config(self, config, version):
    """Handle collection configuration updates"""
    logger.info(f"Collection config version: {version}")

    if "collections" not in config:
        return

    # Parse collections from config
    # Key format: "user:collection" in config["collections"]
    config_collections = set()
    for key in config["collections"].keys():
        if ":" in key:
            user, collection = key.split(":", 1)
            config_collections.add((user, collection))

    # Determine changes
    to_create = config_collections - self.known_collections
    to_delete = self.known_collections - config_collections

    # Create new collections (idempotent)
    for user, collection in to_create:
        try:
            await self.create_collection_internal(user, collection)
            self.known_collections.add((user, collection))
            logger.info(f"Created collection: {user}/{collection}")
        except Exception as e:
            logger.error(f"Failed to create {user}/{collection}: {e}")

    # Delete removed collections (idempotent)
    for user, collection in to_delete:
        try:
            await self.delete_collection_internal(user, collection)
            self.known_collections.discard((user, collection))
            logger.info(f"Deleted collection: {user}/{collection}")
        except Exception as e:
            logger.error(f"Failed to delete {user}/{collection}: {e}")
  1. تهيئة المجموعات المعروفة عند بدء التشغيل:
async def start(self):
    """Start the processor"""
    await super().start()
    await self.sync_known_collections()

async def sync_known_collections(self):
    """Query backend to populate known_collections set"""
    # Backend-specific implementation:
    # - Milvus/Pinecone/Qdrant: List collections/indexes matching naming pattern
    # - Cassandra: Query keyspaces or collection metadata
    # - Neo4j/Memgraph/FalkorDB: Query CollectionMetadata nodes
    pass
  1. إعادة هيكلة طرق المعالجة الحالية:
# Rename and remove response sending:
# handle_create_collection → create_collection_internal
# handle_delete_collection → delete_collection_internal

async def create_collection_internal(self, user, collection):
    """Create collection (idempotent)"""
    # Same logic as current handle_create_collection
    # But remove response producer calls
    # Handle "already exists" gracefully
    pass

async def delete_collection_internal(self, user, collection):
    """Delete collection (idempotent)"""
    # Same logic as current handle_delete_collection
    # But remove response producer calls
    # Handle "not found" gracefully
    pass
  1. إزالة البنية التحتية لإدارة التخزين: إزالة الإعداد والتشغيل self.storage_request_consumer. إزالة الإعداد self.storage_response_producer. إزالة طريقة الموزع on_storage_management. إزالة المقاييس لإدارة التخزين. إزالة الاستيرادات: StorageManagementRequest، StorageManagementResponse.

اعتبارات خاصة بالخلفية:

مخازن المتجهات (Milvus, Pinecone, Qdrant): تتبع (user, collection) المنطقية في known_collections، ولكن قد يتم إنشاء مجموعات خلفية متعددة لكل بُعد. استمر في نمط الإنشاء الكسول. يجب أن تزيل عمليات الحذف جميع المتغيرات الأبعاد.

Cassandra Objects: المجموعات هي خصائص الصفوف، وليست هياكل. تتبع معلومات على مستوى مساحة المفاتيح.

مخازن الرسوم البيانية (Neo4j, Memgraph, FalkorDB): استعلام عن عقد CollectionMetadata عند بدء التشغيل. إنشاء/حذف عقد البيانات الوصفية عند المزامنة.

Cassandra Triples: استخدم واجهة برمجة التطبيقات KnowledgeGraph لعمليات المجموعة.

نقاط التصميم الرئيسية:

الاتساق النهائي: لا يوجد آلية طلب/استجابة، يتم بث دفع التكوين. التكرار: يجب أن تكون جميع عمليات الإنشاء/الحذف آمنة لإعادة المحاولة. معالجة الأخطاء: سجل الأخطاء ولكن لا تقاطع تحديثات التكوين. التعافي الذاتي: ستعيد العمليات الفاشلة المحاولة في دفع التكوين التالي. تنسيق مفتاح المجموعة: "user:collection" في config["collections"].

التغيير 11: تحديث مخطط المجموعة - إزالة الطوابع الزمنية

الملف: trustgraph-base/trustgraph/schema/services/collection.py

تعديل CollectionMetadata (الأسطر 13-21): إزالة الحقول created_at و updated_at:

class CollectionMetadata(Record):
    user = String()
    collection = String()
    name = String()
    description = String()
    tags = Array(String())
    # Remove: created_at = String()
    # Remove: updated_at = String()

تعديل طلب إدارة المجموعة (الأسطر من 25 إلى 47): إزالة حقول الطابع الزمني:

class CollectionManagementRequest(Record):
    operation = String()
    user = String()
    collection = String()
    timestamp = String()
    name = String()
    description = String()
    tags = Array(String())
    # Remove: created_at = String()
    # Remove: updated_at = String()
    tag_filter = Array(String())
    limit = Integer()

السبب: لا تضيف الطوابع الزمنية قيمة للمجموعات. خدمة التكوين تحتفظ بآلية تتبع الإصدار الخاصة بها. تبسط المخطط وتقلل التخزين.

فوائد ترحيل خدمة التكوين

  1. تقضي على مواضيع إدارة التخزين المضمنة بشكل ثابت - تحل مشكلة المستخدمين المتعددين.
  2. تنسيق أبسط - لا يوجد انتظار غير متزامن معقد لـ 4+ استجابات للتخزين.
  3. الاتساق النهائي - تقوم خدمات التخزين بالتحديث بشكل مستقل عبر دفع التكوين.
  4. موثوقية أفضل - دفع تكوين دائم مقابل طلب/استجابة غير دائمة.
  5. نموذج تكوين موحد - يتم التعامل مع المجموعات على أنها تكوين.
  6. تقلل التعقيد - تزيل حوالي 300 سطر من كود التنسيق.
  7. جاهزة لدعم المستخدمين المتعددين - تدعم التكوين بالفعل عزل المستخدمين عبر مساحة المفاتيح.
  8. تتبع الإصدار - توفر آلية إصدار خدمة التكوين مسار تدقيق.

ملاحظات التنفيذ

التوافق مع الإصدارات السابقة

تغييرات في المعلمات: إعادة تسمية معلمات سطر الأوامر هي تغييرات جذرية ولكنها مقبولة (الميزة غير وظيفية حاليًا). تعمل الخدمات بدون معلمات (تستخدم القيم الافتراضية). تم الحفاظ على مساحات المفاتيح الافتراضية: "config" و "knowledge" و "librarian". قائمة الانتظار الافتراضية: persistent://tg/config/config

إدارة المجموعات: تغيير جذري: تمت إزالة جدول المجموعات من مساحة مفاتيح librarian. لا يتم توفير ترحيل للبيانات - مقبول لهذه المرحلة. واجهة برمجة تطبيقات المجموعة الخارجية لم تتغير (عمليات القائمة/التحديث/الحذف). تم تبسيط تنسيق بيانات تعريف المجموعة (تمت إزالة الطوابع الزمنية).

متطلبات الاختبار

اختبار المعلمات:

  1. تحقق من أن المعلمة --config-push-queue تعمل على خدمة graph-embeddings.
  2. تحقق من أن المعلمة --config-push-queue تعمل على خدمة text-completion.
  3. تحقق من أن المعلمة --config-push-queue تعمل على خدمة التكوين.
  4. تحقق من أن المعلمة --cassandra-keyspace تعمل لخدمة التكوين.
  5. تحقق من أن المعلمة --cassandra-keyspace تعمل لخدمة cores.
  6. تحقق من أن المعلمة --cassandra-keyspace تعمل لخدمة librarian.
  7. تحقق من أن الخدمات تعمل بدون معلمات (تستخدم القيم الافتراضية).
  8. تحقق من نشر متعدد المستخدمين باستخدام أسماء قوائم الانتظار ومساحات المفاتيح المخصصة.

اختبار إدارة المجموعات: 9. تحقق من العملية list-collections عبر خدمة التكوين. 10. تحقق من أن update-collection تقوم بإنشاء/تحديث في جدول التكوين. 11. تحقق من أن delete-collection تقوم بإزالة من جدول التكوين. 12. تحقق من أن دفع التكوين يتم تشغيله عند تحديث المجموعات. 13. تحقق من أن تصفية العلامات تعمل مع التخزين المستند إلى التكوين. 14. تحقق من أن عمليات المجموعة تعمل بدون حقول الطوابع الزمنية.

مثال النشر متعدد المستخدمين

# Tenant: tg-dev
graph-embeddings \
  -p pulsar+ssl://broker:6651 \
  --pulsar-api-key <KEY> \
  --config-push-queue persistent://tg-dev/config/config

config-service \
  -p pulsar+ssl://broker:6651 \
  --pulsar-api-key <KEY> \
  --config-push-queue persistent://tg-dev/config/config \
  --cassandra-keyspace tg_dev_config

تحليل الأثر

الخدمات المتأثرة بالتغيير 1-2 (إعادة تسمية معلمة سطر الأوامر)

جميع الخدمات التي ترث من AsyncProcessor أو FlowProcessor: config-service cores-service librarian-service graph-embeddings document-embeddings text-completion-* (جميع المزودين) extract-* (جميع أدوات الاستخراج) query-* (جميع خدمات الاستعلام) retrieval-* (جميع خدمات استرجاع المعلومات) storage-* (جميع خدمات التخزين) وأكثر من 20 خدمة أخرى

الخدمات المتأثرة بالتغييرات 3-6 (مساحة مفاتيح Cassandra)

config-service cores-service librarian-service

الخدمات المتأثرة بالتغييرات 7-11 (إدارة المجموعات)

التغييرات الفورية: librarian-service (collection_manager.py, service.py) tables/library.py (إزالة جدول المجموعات) schema/services/collection.py (إزالة الطابع الزمني)

التغييرات المكتملة (التغيير 10): جميع خدمات التخزين (11 إجمالاً) - تم ترحيلها إلى دفع التكوين لتحديثات المجموعة عبر CollectionConfigHandler تم إزالة مخطط إدارة التخزين من storage.py

اعتبارات مستقبلية

نموذج مساحة مفاتيح خاصة بالمستخدم

تستخدم بعض الخدمات مساحات مفاتيح خاصة بالمستخدم ديناميكيًا، حيث يحصل كل مستخدم على مساحة مفاتيح Cassandra خاصة به:

الخدمات التي تستخدم مساحات مفاتيح خاصة بالمستخدم:

  1. خدمة استعلام الثلاثيات (trustgraph-flow/trustgraph/query/triples/cassandra/service.py:65) تستخدم keyspace=query.user
  2. خدمة استعلام الكائنات (trustgraph-flow/trustgraph/query/objects/cassandra/service.py:479) تستخدم keyspace=self.sanitize_name(user)
  3. الوصول المباشر إلى الرسم البياني المعرفي (trustgraph-flow/trustgraph/direct/cassandra_kg.py:18) المعلمة الافتراضية keyspace="trustgraph"

الحالة: هذه غير معدلة في هذا المواصفات.

مراجعة مستقبلية مطلوبة: تقييم ما إذا كانت نموذج مساحة مفاتيح خاصة بالمستخدم تخلق مشاكل عزل المستأجر ضع في اعتبارك ما إذا كانت عمليات النشر متعددة المستأجرين تحتاج إلى أنماط بادئة لمساحة مفاتيح (مثل tenant_a_user1) مراجعة للاحتمالية المحتملة لتصادم معرف المستخدم عبر المستأجرين تقييم ما إذا كانت مساحة مفاتيح مشتركة واحدة لكل مستأجر مع عزل الصفوف المستند إلى المستخدم هي الأفضل

ملاحظة: هذا لا يمنع التنفيذ متعدد المستأجرين الحالي ولكنه يجب مراجعته قبل عمليات نشر متعددة المستأجرين في الإنتاج.

مراحل التنفيذ

المرحلة 1: إصلاحات المعلمات (التغييرات 1-6)

إصلاح تسمية المعلمة --config-push-queue إضافة دعم المعلمة --cassandra-keyspace النتيجة: تم تمكين قائمة الانتظار متعددة المستأجرين وتكوين مساحة المفاتيح

المرحلة 2: ترحيل إدارة المجموعة (التغييرات 7-9، 11)

ترحيل تخزين المجموعة إلى خدمة التكوين إزالة جدول المجموعات من librarian تحديث مخطط المجموعة (إزالة الطوابع الزمنية) النتيجة: يلغي إدارة التخزين المضمنة، ويبسط librarian

المرحلة 3: تحديثات خدمة التخزين (التغيير 10) مكتمل

تم تحديث جميع خدمات التخزين لاستخدام دفع التكوين للمجموعات عبر CollectionConfigHandler تمت إزالة البنية التحتية لطلبات واستجابات إدارة التخزين تمت إزالة تعريفات المخطط القديمة النتيجة: تم تحقيق إدارة المجموعة المستندة إلى التكوين بالكامل

المراجع

مشكلة GitHub: https://github.com/trustgraph-ai/trustgraph/issues/582 الملفات ذات الصلة: trustgraph-base/trustgraph/base/async_processor.py trustgraph-base/trustgraph/base/cassandra_config.py trustgraph-base/trustgraph/schema/core/topic.py trustgraph-base/trustgraph/schema/services/collection.py trustgraph-flow/trustgraph/config/service/service.py trustgraph-flow/trustgraph/cores/service.py trustgraph-flow/trustgraph/librarian/service.py trustgraph-flow/trustgraph/librarian/collection_manager.py trustgraph-flow/trustgraph/tables/library.py