GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Zeitsynchronisation in einer heterogenen Umgebung

[BEARBEITEN] Eine große Neufassung mit Referenzen, da ich gerade die alte Antwort aus dem Gedächtnis aufgeschrieben habe.

Kurze Antwort:nein. Es ist heute nicht möglich, mit einem gewöhnlichen Betriebssystem auf einer x86/x64-Plattform eine Genauigkeit von nahezu einer Millisekunde zu erreichen.

HAFTUNGSAUSSCHLUSS Dies ist eine Laienantwort, da ich ein gewöhnlicher Systemadministrator mit einer gewöhnlichen Systemadministratoransicht von Computern bin. Einige Kernel-Entwickler und Hardware-Architekten verfügen wahrscheinlich über ein professionelles Wissen über die Zeitmessung.

Lange Antwort:

Irgendwo muss man ja anfangen. Ich werde dies von oben nach unten tun, beginnend mit Anwendungen, die sich nach unten zu den Oszillatoren bewegen.

Das erste Problem besteht darin, die Zeiterfassung nicht auf einem Computer zu haben, sondern es zu schaffen, die Umgebung als Ganzes dazu zu bringen, sich auf die Zeiterfassung zu einigen, die Sie haben. Welche Zeitmessung? Es stellt sich heraus, dass es ein paar Möglichkeiten gibt, die Zeit in einem Computer von heute zu halten. Diejenige, von der wir am meisten sehen, ist die Systemzeit (wie sie in einer der Bildschirmecken angezeigt wird). Beginnen wir damit, so zu tun, als wäre es so einfach, und verkomplizieren die Dinge ein paar Absätze weiter unten.

Wir möchten, dass die Systemzeit korrekt und auf allen unseren Computern einheitlich ist. Wir brauchen eine Möglichkeit, es von einer vertrauenswürdigen Quelle auf einer so detaillierten Ebene zu kommunizieren, dass wir unsere Anforderungen erfüllen können, welche auch immer sie sein mögen.

Machen wir unsere Anforderung zu einem Toleranzwert von 1 ms, das heißt, unsere Zeit kann innerhalb unserer Umgebung um 1 ms abweichen oder wir verfehlen ein kritisches Ziel. Lassen Sie uns konkret werden und uns ansehen, was Microsoft für uns tun kann.

Abgesehen von veralteten Systemen wie NT führt Windows native seine Zeitmessung entweder auf der Grundlage von vereinfachtem ntp (Computer mit Domänenbeitritt, beginnend mit XP/2003) oder vereinfachtem sntp (Computer, die nicht mit Domänen verbunden sind, beginnend mit Win2k) aus - danke an @Ryan für die Spitzfindigkeit dieses Details . Microsoft hat sich bei der Implementierung der Zeiterfassung zwei Ziele gesetzt, von denen keines unser gewünschtes Maß an Genauigkeit einschließt:

"Wir garantieren nicht und unterstützen nicht die Genauigkeit des W32Time-Dienstes zwischen Knoten in einem Netzwerk. Der W32Time-Dienst ist keine NTP-Lösung mit vollem Funktionsumfang, die zeitkritische Anwendungsanforderungen erfüllt. Der W32Time-Dienst ist in erster Linie darauf ausgelegt Folgendes tun:

  • Authentifizierungsprotokoll Kerberos Version 5 zum Laufen bringen.
  • Stellen Sie lose Synchronisierungszeit für Client-Computer bereit.

Der W32Time-Dienst kann die Synchronisierungszeit nicht zuverlässig im Bereich von ein bis zwei Sekunden halten. Solche Toleranzen liegen außerhalb der Designspezifikation des W32Time-Dienstes."

OK. Angenommen, wir führen Ihren Service-Stack auf mehr als einem Computer aus und haben eine Zeitmessungstoleranz von fast 1 ms für die Ereigniskorrelation, dann ist das eine ziemliche Enttäuschung. Wenn der Service-Stack zwei Computer umfasst, können wir die native Windows-Zeiterfassung überhaupt nicht verwenden. Aber wenn wir schon dabei sind, lassen Sie uns ein oder zwei wichtige Punkte über die Windows-eigene Zeitmessung unterstreichen und eine ausführliche Dokumentation hinzufügen:

Wenn Sie ein AD haben, beachten Sie, dass die Zeit in einer bestimmten Domäne von der PDC-Emulatorrolle synchronisiert wird, unabhängig davon, welcher DC sie hat. Das Einbringen der korrekten Zeit in die Domäne muss daher über den Domänencontroller erfolgen, auf dem die Rolle des PDC-Emulators ausgeführt wird. In einer Gesamtstruktur mit mehreren Domänen wird dies in den PDC-Emulator der Stammdomäne der Gesamtstruktur übersetzt. Von dort wird die Zeit hauptsächlich auf die PDC-Emulatoren von Unterdomänen und auf jedes Domänenmitglied verteilt (mit einigen Vorbehalten). Dieser Vorgang ist hier dokumentiert. Noch mehr ausführliche Informationen hier

OK. Was können wir tun?

Zunächst benötigen wir die eine oder andere genauere Möglichkeit, die Zeit in der gesamten Umgebung zu synchronisieren. Angenommen, wir können Linux ntpd oder ntpd für Windows nicht ausführen, könnten Sie einen Blick auf einen Shareware-Client namens Tardis werfen, aber es gibt wahrscheinlich noch viel mehr, die Sie ausprobieren können.

Wir haben Tardis auf einem Win2k3-Server ausgeführt, der als PDC-Emulator lief, der eine CMOS-Uhr mit einem wirklich großen Versatz hatte, aus unerklärlichen historischen Gründen hatten wir keine andere Wahl, als das gesamte Netzwerk von ihm zu synchronisieren. Jetzt wurde es zu großer Freude durch einen dedizierten Linux-ntpd ersetzt, der die Zeit von Atomuhren auf der Außenseite einbringt, aber Tardis hat uns damals und dort bewundernswert gerettet. Ich weiß jedoch nicht, ob es Ihnen helfen könnte, eine höhere Genauigkeit als bei Windows zu erreichen.

Aber nehmen wir ab diesem Punkt an, dass wir (uns) herausgefunden haben, wie man eine perfekte Ersatznetzzeitsynchronisation umsetzt. Durch seine inhärente Schlauheit hat es eine Kapazität für Toleranzwerte unter einer Millisekunde. Wir haben es eingerichtet, um zu erzwingen, wie unser AD erwartet, dass sich die Zeit über das Netzwerk ausbreitet.

Bedeutet dies, dass wir genaue Diagnosen von Betriebssystemen und Microservices mit einer Granularität von nahezu einzelnen Millisekunden erhalten können?

Sehen wir uns an, wie Betriebssysteme auf der x86/x64-Architektur die Prozessorzeit planen.

Sie verwenden Interrupts, die facettenreiche Bestien sind, die reich an archäologischer Substanz sind. Das Betriebssystem ist jedoch nicht allein in seinem Wunsch zu unterbrechen. Die Hardware will auch unterbrechen, und sie hat die Mittel dazu! (Hallo Keyboard) Und Betriebssysteme spielen mit.

Hier wird es kompliziert und ich werde das lösen, indem ich zu stark vereinfache. Fragen? Ich ducke mich, decke ab und weise Sie auf eine absolut hervorragende Abhandlung zu diesem Thema hin. (Wenn Sie Millisekunden auf einer Windows-Plattform jagen, sollten Sie es wirklich lesen.) Eine aktualisierte Version für Win8.1/Win2012r2 ist Berichten zufolge in Arbeit, aber es ist noch kein Veröffentlichungsdatum aufgetaucht.

OK, unterbricht. Immer wenn in einem Betriebssystem etwas passieren sollte, löst ein Interrupt die folgende Aktion aus. Die Aktion besteht aus einer Reihe von Anweisungen, die aus dem Kernel abgerufen werden und auf viele verschiedene Arten ausgeführt werden können. Die Quintessenz ist, dass, obwohl der Interrupt zu einem Zeitpunkt auftritt, der je nach Hardwarearchitektur und Kernel-Interrupt-Behandlung mehr oder weniger genau bestimmt werden kann, der genaue Zeitpunkt, zu dem die nachfolgenden Teile der Ausführung stattfinden, im Allgemeinen nicht möglich ist. Ein bestimmter Befehlssatz kann früh oder spät nach dem Interrupt ausgeführt werden, er kann in einer vorhersehbaren Reihenfolge ausgeführt werden oder nicht, er kann Opfer fehlerhafter Hardware oder schlecht geschriebener Treiber sein, die Latenzen beeinträchtigen, die schwer zu erkennen sind. Meistens weiß man es einfach nicht. Der Zeitstempel auf Millisekundenebene, der in der nachfolgenden Protokolldatei angezeigt wird - er ist sehr genau, aber ist er genau, wann das Ereignis eingetreten ist?

Halten wir kurz beim Timekeeping-Interrupt an. Ein Interrupt hat eine Prioritätsstufe, auf der niedrigsten Stufe erhalten Benutzeranwendungen (z. B. ein Standarddienst) ihre Prozessorzeit. Die anderen (höheren) Ebenen sind für Hardware und Kernel-Arbeit reserviert. Wenn ein Interrupt auf einer Ebene über dem niedrigsten ankommt, wird das System so tun, als gäbe es keine Interrupts mit niedrigerer Priorität, die sich auch in der Warteschlange befinden (bis Interrupts mit höherer Priorität behandelt wurden). Die normalen Anwendungen und Dienste, die ausgeführt werden, werden auf diese Weise als letzte in der Prozessorzeit anstehen. Im Gegensatz dazu wird dem Taktinterrupt fast die höchste Priorität eingeräumt. Die Aktualisierung der Zeit wird fast immer in einem System durchgeführt. Dies ist eine fast kriminelle Vereinfachung dessen, wie alles funktioniert, aber es dient dem Zweck dieser Antwort.

Die Aktualisierungszeit besteht eigentlich aus zwei Aufgaben:

  • Aktualisieren der Systemzeit / AKA die Wanduhr / AKA was ich sage, wenn mich jemand fragt, wie spät es ist / AKA das Ding ntp fummelt ein bisschen hin und her relativ zu benachbarten Systemen.

  • Aktualisieren des Tick-Zählers, der zum Beispiel beim Messen der Dauer bei der Codeausführung verwendet wird.

Aber ob Walltime oder Tickcount, woher bekommt das System die Zeit? Es hängt stark von der Hardwarearchitektur ab. Irgendwo in der Hardware ticken ein oder mehrere Oszillatoren, und dieses Ticken wird über einen von mehreren möglichen Pfaden in eine Schnittstelle zum Kontakt mit dem Kernel gebracht, während dieser mit mehr oder weniger Präzision und Genauigkeit seine Wandzeit und Tickzahl aktualisiert.

Es gibt mehrere Designmodelle für die Oszillatorplatzierung in einem Multicore-System, das Hauptunterscheidungsmerkmal scheint die synchrone vs. asynchrone Platzierung zu sein. Diese werden zusammen mit ihren jeweiligen Herausforderungen für eine genaue Zeitmessung beispielsweise hier beschrieben.

Kurz gesagt, die synchrone Zeitmessung hat eine Referenzuhr pro Multicore, die ihr Signal auf alle Kerne verteilt bekommt. Die asynchrone Zeitmessung hat einen Oszillator pro Kern. Es ist erwähnenswert, dass die neuesten Intel-Multicore-Prozessoren (Haswell) eine Art synchrones Design mit einem seriellen Bus namens „QuickPath Interconnect“ mit „Forwarded Clocking“ verwenden, Ref. Datenblatt. Das Forwarded Clocking ist so beschrieben, dass ein Laie (ich) es hier schnell oberflächlich erfassen kann.

OK, also mit all dem Nerderismus aus dem Weg (der gezeigt hat, dass die Zeitmessung eine komplexe praktische Aufgabe mit viel lebendiger Geschichte ist), lasst uns noch genauer auf die Behandlung von Interrupts schauen.

Betriebssysteme handhaben Interrupts mit einer von zwei unterschiedlichen Strategien:Ticking oder Tickless. Ihre Systeme verwenden das eine oder andere, aber was bedeuten die Begriffe?

Kerne ticken Senden von Interrupts in festen Intervallen. Das Betriebssystem kann die Zeit nicht mit einer feineren Auflösung als dem Tickintervall messen. Selbst dann kann die eigentliche Verarbeitung, die mit der Durchführung einer oder mehrerer Aktionen verbunden ist, durchaus eine Verzögerung enthalten, die größer ist als das Tick-Intervall. Betrachten Sie zum Beispiel verteilte Systeme (wie Microservices), bei denen Verzögerungen, die mit Anrufen zwischen Diensten einhergehen, relativ viel Zeit in Anspruch nehmen könnten. Dennoch wird jeder Befehlssatz einem oder mehreren Interrupts zugeordnet, die vom Betriebssystem mit einer Auflösung gemessen werden, die nicht kleiner als die Tickzeit des Kernels ist. Die Tickzeit hat einen Basiswert, kann aber zumindest in Windows bei Bedarf durch eine einzelne Anwendung verringert werden. Eine Aktion, die nicht nur mit Nutzen, sondern auch mit Kosten verbunden ist und einiges an Kleingedrucktem mit sich bringt.

Sogenannte Tickless-Kernel (die einen sehr nicht aussagekräftigen Namen haben) sind eine relativ neue Erfindung. Ein Tickless-Kernel setzt die Tick-Zeit in variablen Intervallen (möglichst lange Dauer in die Zukunft). Der Grund dafür ist, dass das Betriebssystem den Prozessorkernen dynamisch ermöglicht, so lange wie möglich in verschiedene Ruhezustandsstufen zu wechseln, mit dem einfachen Zweck, Strom zu sparen. "Verschiedene Ebenen" umfassen die Verarbeitung von Anweisungen mit voller Geschwindigkeit, die Verarbeitung mit verringerten Raten (d. h. langsamere Prozessorgeschwindigkeit) oder überhaupt keine Verarbeitung. Verschiedene Kerne dürfen mit unterschiedlichen Geschwindigkeiten arbeiten, und der Tickless-Kernel versucht, Prozessoren so inaktiv wie möglich zu lassen, selbst in Fällen, in denen Anweisungen in die Warteschlange gestellt werden, um sie in Interrupt-Batches abzufeuern. Kurz gesagt, verschiedene Kerne in einem Mehrprozessorsystem dürfen zeitlich relativ zueinander driften. Dies ist natürlich verheerend für eine gute Zeitmessung und ist bisher ein ungelöstes Problem mit neueren energiesparenden Prozessorarchitekturen und den tickless Kerneln, die ihnen eine effiziente Energieeinsparung ermöglichen. Vergleichen Sie dies mit einem tickenden Kernel (statisches Tickintervall), der alle Prozessorkerne kontinuierlich aufweckt, unabhängig davon, ob sie tatsächliche Arbeit erhalten oder nicht, und bei dem die Zeitmessung im Vergleich zu ticklosen Kerneln ein gewisses Maß an Ungenauigkeit, aber relativ zuverlässig aufweist.

Die Standard-Tick-Zeit von Windows – das ist die Systemauflösung – beträgt 15,6 ms bis Windows 8/2012, wo das Standardverhalten tickless ist (aber auf tickenden Kernel umkehrbar ist). Die Standard-Tick-Zeit von Linux hängt meines Erachtens von der Kernel-Kompilierung ab, aber diese Nische liegt weit außerhalb meiner Erfahrung (und auch dieser), sodass Sie vielleicht noch einmal überprüfen möchten, ob Sie darauf angewiesen sind. Ich glaube, Linux-Kernel sind ab 2.6.21 tickless kompiliert und können mit verschiedenen Flags kompiliert werden, die das tickless-Verhalten optimieren (und von denen ich mich nur an einige wenige Varianten von no_hz erinnere).

So viel zu Bare-Metal-Systemen. In virtuellen Systemen wird es noch schlimmer, da VM- und Hypervisor-Konflikte auf unterschiedliche Weise eine genaue Zeitmessung extrem schwierig machen. Hier ist eine Übersicht für VMware und hier eine für RHEL KVM. Dasselbe gilt für verteilte Systeme. Cloud-Systeme sind noch schwieriger, da wir nicht einmal annähernd an tatsächliche Hypervisoren und Hardware herankommen.

Zusammenfassend lässt sich sagen, dass das Abrufen einer genauen Zeit aus einem System ein vielschichtiges Problem ist. Gehen wir nun von oben nach oben, müssen wir Folgendes lösen:Interne Zeitsynchronisation zwischen der Hardware und dem Kernel, Unterbrechungsverarbeitung und Verzögerungen bei der Ausführung der Anweisungen, die wir wünschen, wenn in einer virtuellen Umgebung Ungenauigkeiten auftreten aufgrund der Kapselung einer zweiten OS-Schicht die Zeitsynchronisation zwischen verteilten Systemen.

Daher werden wir an diesem Punkt in der Geschichte des Computing keine Millisekunden-Genauigkeit aus einer x86/x64-Architektur herausholen, zumindest nicht mit einem der gewöhnlichen Betriebssysteme.

Aber wie nah können wir ihm kommen? Ich weiß es nicht und es sollte zwischen verschiedenen Systemen stark variieren. Die Ungenauigkeit in den eigenen spezifischen Systemen in den Griff zu bekommen, ist eine entmutigende Aufgabe. Man muss sich nur ansehen, wie Intel Code-Benchmarking vorschlägt, um zu sehen, dass gewöhnliche Systeme, wie die, die ich gerade verwalte, in dieser Hinsicht sehr außer Kontrolle geraten sind.

Ich denke nicht einmal daran, "Alle Leistungsoptimierung, Intel Hyper-Threading-Technologie, Frequenzskalierung und Turbo-Modus-Funktionalitäten wurden abgeschaltet" zu erreichen in kritischen Systemen, geschweige denn an Code-Wrappern in C basteln und Langzeittests durchführen, um nachfolgende Antworten zu erhalten. Ich versuche einfach, sie am Leben zu erhalten und so viel wie möglich über sie zu lernen, ohne sie zu sehr zu stören. Danke, Zeitstempel, ich weiß, dass ich dir nicht voll vertrauen kann, aber ich weiß, dass du nicht allzu viele Sekunden daneben bist. Wenn die tatsächliche Genauigkeit im Millisekundenbereich wichtig wird, reicht eine Messung nicht aus, sondern es ist eine größere Anzahl von Messungen erforderlich, um das Muster zu verifizieren. Was können wir sonst noch tun?

Schließlich ist es interessant zu sehen, wie die Echtzeit-OS-Leute denken, Latenzzeiten zu unterbrechen. Es ist auch eine sehr aufregende Zeitsynchronisierungsalternative in Arbeit, bei der eine ganze Reihe interessanter Statistiken, Methoden und Whitepapers veröffentlicht werden. Fügen Sie dazu zukünftige Hardwarearchitekturen und Kernel-Entwicklungen hinzu, und in ein paar Jahren ist diese Sache mit der Genauigkeit der Zeitmessung möglicherweise kein solches Problem mehr. Man darf hoffen.


Linux
  1. Linux schneller booten

  2. Umgebungsvariablen *in* /etc/environment referenzieren?

  3. C# in Linux-Umgebung

  4. Zeit vorübergehend ändern

  5. Dateisynchronisierung in Echtzeit

So richten Sie die Zeitsynchronisierung unter Ubuntu ein

Terminplanung mit cron &At

Systemzeit

Zeitanzeige zeigt Datum/Uhrzeit nicht an?

Linux-Umgebungsvariablen

So richten Sie die Zeitsynchronisierung mit NTP unter Ubuntu 18.04 ein