Mehr

Wie lade ich mehrere Shapefiles in dieselbe vorhandene Feature-Class?

Wie lade ich mehrere Shapefiles in dieselbe vorhandene Feature-Class?


Ich habe Hunderte von Shapefiles und muss sie basierend auf dem Dateinamen in eine von drei Feature-Classes (Punkte, Polylinien oder Polygone) laden. Mein Code funktioniert, bis er versucht, die zweite Datei eines bestimmten Typs zu laden. Dann erhalte ich eine Fehlermeldung "FC_NAME existiert bereits". Ja, es existiert bereits, genau das will ich. Laden Sie nun bitte das Shapefile in die Feature-Class!

Wie lade ich ein Shapefile in eine vorhandene Feature-Class?

Hier ist der Code, gekürzt, um die Logik auszuschließen, die bis zu diesem Punkt führt:

result = arcpy.FeatureClassToFeatureClass_conversion(shp, outputLocation, outputPointsFC)

Hier ist ein Skript, das ich zufällig herumliegen habe, es führt alle Linien, Punkte und Polygone aus einer Datenbank in eine neue Datenbank-Feature-Class zusammen; es gibt keine Feldzuordnung, zu diesem Zeitpunkt wollten wir nur alle Geometrien zusammen sehen, ohne über 1k-Layer laden zu müssen…

Eine Feature-Class (Shapefile oder Datenbank) kann nur einen Geometrietyp speichern, daher ist es wichtig, diesen zu testen, bevor Sie entscheiden, wo er abgelegt werden soll.

import arcpy, os, sys # Setzen Sie Ihre Parameter Eingabe- und Ausgabedatenbank InDB = sys.argv[1] OutDB = sys.argv[2] falls nicht os.path.exists(OutDB): DBpath = os.path.dirname(OutDB ) DBname = os.path.basename(OutDB) name,ext = os.path.splitext(DBname) if ext.upper() == ".MDB": arcpy.AddMessage("Erstellen der persönlichen Ausgabedatenbank") arcpy.CreatePersonalGDB_management (DBpath,DBname) elif ext.upper() == ".GDB": arcpy.AddMessage("Ausgabedateidatenbank erstellen") arcpy.CreateFileGDB_management(DBpath,DBname) else: arcpy.AddError("Unbekanntes Ausgabedatenbankformat") # Ihren Arbeitsbereich für ListDatasets festlegen arcpy.env.workspace = InDB # leere Listen erstellen LineList = list() PointList = list() PolyList = list() # Eigenständige Feature-Classes für FeatClass in arcpy.ListFeatureClasses(): desc = arcpy.Describe (InDB + "" + FC + "" + FeatClass) if desc.shapeType == "Point": PointList.append(InDB + "" + FC + "" + FeatClass) elif desc. shapeType == "Polyline": LineList.append(InDB + "" + FC + "" + FeatClass) elif desc.shapeType == "Polygon": PolyList.append(InDB + "" + FC + "" + FeatClass) # Feature-Datasets für FC in arcpy.ListDatasets() durchlaufen: arcpy.env.workspace = InDB + "" + FC für FeatClass in arcpy.ListFeatureClasses(): desc = arcpy.Describe(InDB + "" + FC + "" + FeatClass) if desc.shapeType == "Point": PointList. append(InDB + "" + FC + "" + FeatClass) elif desc.shapeType == "Polyline": LineList.append(InDB + "" + FC + "" + FeatClass) elif desc .shapeType == "Polygon": PolyList.append(InDB + "" + FC + "" + FeatClass) arcpy.AddMessage("Zusammenführung durchführen") if len(PointList) > 0: arcpy.Merge_management(PointList ,OutDB + "Merged_Points") if len(LineList) > 0: arcpy.Merge_management(LineList,OutDB + "Merged_Lines") if len(PolyList) > 0: arcpy.Merge_management(PolyList,OutDB + " Merged_Polygons")

Wenn Sie ersetzenarcpy.Merge_management(einen Haufen zu einer neuen Feature-Class zusammenschlagen) mitarcpy.Append_management(Fügen Sie eine Reihe von Feature-Classes in eine vorhandene Feature-Class ein), dann sollte es so ziemlich das tun, was Sie wollen - wenn Sie dies tun, müssen Sie auch die Ausgabe in den vollständigen Pfad zu den vorhandenen Datasets ändern, in die eingefügt werden soll.


Entweder ausgewählte Features oder Features in der Ansichtsausdehnung auf mehreren Layern als Shapefiles exportieren?

Regelmäßig muss ich Features aus mehreren Layern als Shapefiles exportieren. Aber in 99% der Fälle benötige ich nicht alle Funktionen in jeder Ebene.

Alles, was ich herausfinden konnte, ist entweder

mit den "Konvertierungstools->To Shapefile". Dadurch kann ich mehrere Ebenen auswählen, aber alle Funktionen werden gelöscht (ich benötige nicht jede Topo-Linie oder jedes Paket im Landkreis)

2) Gehen Sie zu jeder Ebene und führen Sie den Vorgang "Export Data->Features in viewausmaß" durch, was ein ziemlich langer Prozess sein kann.

Wenn Sie in jede Ebene gehen und auswählen, was Sie möchten, ignoriert jedes Werkzeug, das Sie darauf ausführen, die nicht ausgewählten Elemente.

Zum Exportieren mehrerer Shapefiles verwende ich normalerweise das Werkzeug "Feature-Class zu Geodatabase (mehrere)" (Konvertierungswerkzeuge > zu Geodatabase > Feature-Class zu Geodatabase). Es hört sich so an, als würden keine Shapefiles erstellt, aber wenn Sie die Ausgabe nur auf einen Ordner verweisen, werden Shapefiles direkt dorthin exportiert.

Ich bin mir jedoch nicht sicher, ob ich das alles im Rahmen der Ansicht belassen soll. Ich kann mir vorstellen, dass dies im Dialogfeld "Umgebungen" sein sollte, wenn es möglich ist (Eigentlich denke ich, dass es Verarbeitungsumfang: Gleich wie Anzeige ist).

DAS FUNKTIONIERT (fast. Siehe unten*)

Verwenden Sie entweder die "Conversion Tools > To Geodatabase > Feature Class to Geodatabase" ODER die """Conversion Tools > To Shapefile"

Wenn Sie auf "Umgebungen > Verarbeitungsumfang" klicken und die Option "Wie Anzeige" auswählen, werden nur die auf der Anzeige sichtbaren Funktionen in Shapefiles umgewandelt.

*Hinweis: Ich konnte dies nicht mit den Ebenen in meiner .mxd-Datei zum Laufen bringen. Stattdessen musste ich zurück zur SDE und die Feature-Classes auswählen. Dies bedeutet jedoch, dass ich nicht verwenden kann, wie ich die Informationen in meinem mxd aufgeteilt habe. Zum Beispiel habe ich in meinem mxd eine 10-Fuß-Topo-Linienebene und eine kleinere Konturlinienebene getrennt. Ich kann diese mit keinem der Konvertierungstools exportieren. Das Ergebnis, wenn ich es versuche, ist, dass keine Konvertierung stattfindet. (keine Fehlermeldung, nur keine .shp-Dateien im Ausgabeordner). Es spielt keine Rolle, ob ich die Toolbox in ArcMap oder ArcCatalog verwende.


CacheLoader lädt dieselben Schlüssel mehrmals

Ich rufe einen Webdienst mit SOAP auf, um Policen für eine Versicherungsgesellschaft zu bewerten. Ich versuche, einen Cachebuilder / Loader zu verwenden, um die DTOs als Schlüssel und die Antwort des Dienstes als Wert zu speichern. Nach meinen Recherchen erhalten die Methoden .get und .getUnchecked einen Wert aus dem Cache, und wenn er nicht vorhanden ist, wird dieser Wert in den Cache geladen. hier ist ein Code:

Und hier rufe ich die Methode get auf:

Ich ging davon aus, dass möglicherweise Speicheradressen verglichen wurden, die unterschiedlich sein würden, also überschrieb ich die toString-Methode, um das DTO-Objekt in JSON zu konvertieren. Bei der Überprüfung des Caches kann ich feststellen, dass die Schlüssel mit einem Vergleichstool genau gleich sind. Sie werden jedoch immer noch gespeichert und rufen den Dienst jedes Mal auf. Ich habe versucht, die Methode equals in PolicyDTO zu überschreiben, aber sie wird beim Debuggen nie getroffen.

Wie kann ich dafür sorgen, dass der Cacheloader nur Werte verschiedener Schlüssel lädt und vorhandene Werte so herauszieht, wie es ursprünglich beabsichtigt war?

Ich glaube, ich habe einfach keine solide Vorstellung davon, wie der cacheLoader tatsächlich funktioniert. Ich freue mich über jede Hilfe oder Vorschläge.


Best Practice ist es, in jedem Modul einen Logger wie folgt zu definieren:

am oberen Rand des Moduls, und dann in anderem Code im Modul z.B.

Wenn Sie die Protokollierungsaktivität innerhalb eines Moduls unterteilen müssen, verwenden Sie z.

und protokollieren Sie nach Bedarf in loggerA und loggerB.

Führen Sie in Ihrem Hauptprogramm oder Ihren Hauptprogrammen z. B. aus:

Siehe hier für die Protokollierung von mehreren Modulen und hier für die Protokollierung der Konfiguration für Code, der von anderem Code als Bibliotheksmodul verwendet wird.

Aktualisieren: Wenn Sie fileConfig() aufrufen, möchten Sie möglicherweise disable_existing_loggers=False angeben, wenn Sie Python 2.6 oder höher verwenden (weitere Informationen finden Sie in der Dokumentation). Der Standardwert ist aus Gründen der Abwärtskompatibilität True, was dazu führt, dass alle vorhandenen Logger von fileConfig() deaktiviert werden, es sei denn, sie oder ihr Vorfahre werden in der Konfiguration explizit benannt. Wenn der Wert auf False gesetzt ist, werden vorhandene Logger in Ruhe gelassen. Wenn Sie Python 2.7/Python 3.2 oder höher verwenden, möchten Sie vielleicht die dictConfig() API in Betracht ziehen, die besser ist als fileConfig(), da sie mehr Kontrolle über die Konfiguration gibt.


Sie können definitiv eine einzelne Konfiguration mit mehreren jdbc-Eingaben haben und dann den Index und den document_type in Ihrer elastischen Suche-Ausgabe parametrisieren, je nachdem, aus welcher Tabelle das Ereignis stammt.

Dadurch werden keine doppelten Daten erstellt. und kompatibler Logstash 6x.

Wenn Sie mehr als eine Pipeline im selben Prozess ausführen müssen, bietet Logstash eine Möglichkeit, dies über eine Konfigurationsdatei namens . zu tun Pipelines.yml und verwenden mehrere Pipelines

Die Verwendung mehrerer Pipelines ist besonders nützlich, wenn Ihre aktuelle Konfiguration Ereignisflüsse enthält, die nicht dieselben Eingaben/Filter und Ausgaben verwenden und durch Tags und Bedingungen voneinander getrennt sind.


Inhalt

Ein Load-Balancing-Algorithmus versucht immer, ein bestimmtes Problem zu beantworten. Dabei sind unter anderem die Art der Aufgaben, die algorithmische Komplexität, die Hardwarearchitektur, auf der die Algorithmen ablaufen, sowie die erforderliche Fehlertoleranz zu berücksichtigen. Daher müssen Kompromisse gefunden werden, um anwendungsspezifische Anforderungen am besten zu erfüllen.

Art der Aufgaben Bearbeiten

Die Effizienz von Load-Balancing-Algorithmen hängt entscheidend von der Art der Aufgaben ab. Je mehr Informationen über die Aufgaben zum Zeitpunkt der Entscheidungsfindung vorliegen, desto größer ist daher das Optimierungspotenzial.

Größe der Aufgaben Bearbeiten

Eine perfekte Kenntnis der Ausführungszeit jeder der Aufgaben ermöglicht eine optimale Lastverteilung (siehe Algorithmus der Präfixsumme). [1] Leider ist dies tatsächlich ein idealisierter Fall. Die genaue Ausführungszeit jeder Aufgabe zu kennen, ist eine äußerst seltene Situation.

Aus diesem Grund gibt es verschiedene Techniken, um sich ein Bild von den unterschiedlichen Ausführungszeiten zu machen. In dem glücklichen Szenario, dass Aufgaben relativ homogener Größe vorliegen, kann zunächst davon ausgegangen werden, dass jede von ihnen ungefähr die durchschnittliche Ausführungszeit benötigt. Ist die Ausführungszeit hingegen sehr unregelmäßig, müssen ausgefeiltere Techniken eingesetzt werden. Eine Technik besteht darin, jeder Aufgabe einige Metadaten hinzuzufügen. Abhängig von der bisherigen Ausführungszeit für ähnliche Metadaten ist es möglich, anhand von Statistiken Rückschlüsse auf eine zukünftige Aufgabe zu ziehen. [2]

Abhängigkeiten Bearbeiten

In einigen Fällen hängen die Aufgaben voneinander ab. Diese Abhängigkeiten können durch einen gerichteten azyklischen Graphen veranschaulicht werden. Intuitiv können einige Aufgaben erst beginnen, wenn andere abgeschlossen sind.

Unter der Annahme, dass die benötigte Zeit für jede der Aufgaben im Voraus bekannt ist, muss eine optimale Ausführungsreihenfolge zur Minimierung der Gesamtausführungszeit führen. Obwohl dies ein NP-schweres Problem ist und daher schwer genau zu lösen sein kann. Es gibt Algorithmen, wie den Job-Scheduler, die mit metaheuristischen Methoden optimale Aufgabenverteilungen berechnen.

Aufgabentrennung Bearbeiten

Ein weiteres Merkmal der für den Entwurf eines Lastausgleichsalgorithmus kritischen Aufgaben ist ihre Fähigkeit, während der Ausführung in Teilaufgaben zerlegt zu werden. Der später vorgestellte Algorithmus "Tree-Shaped Computation" macht sich diese Spezifität zunutze.

Statische und dynamische Algorithmen Bearbeiten

Statische Bearbeitung

Ein Load-Balancing-Algorithmus ist "statisch", wenn er den Zustand des Systems bei der Aufgabenverteilung nicht berücksichtigt. Dabei umfasst der Systemzustand Maßnahmen wie den Auslastungsgrad (und manchmal sogar die Überlastung) bestimmter Prozessoren. Stattdessen werden vorab Annahmen zum Gesamtsystem getroffen, wie zum Beispiel die Ankunftszeiten und der Ressourcenbedarf eingehender Aufgaben. Außerdem sind die Anzahl der Prozessoren, ihre jeweilige Leistung und Kommunikationsgeschwindigkeiten bekannt. Daher zielt der statische Lastausgleich darauf ab, den verfügbaren Prozessoren einen bekannten Satz von Aufgaben zuzuordnen, um eine bestimmte Leistungsfunktion zu minimieren. Der Trick liegt im Konzept dieser Leistungsfunktion.

Statische Lastausgleichstechniken werden üblicherweise um einen Router oder Master herum zentralisiert, der die Lasten verteilt und die Leistungsfunktion optimiert. Diese Minimierung kann Informationen bezüglich der zu verteilenden Aufgaben berücksichtigen und eine erwartete Ausführungszeit ableiten.

Statische Algorithmen haben den Vorteil, dass sie einfach einzurichten und bei recht regelmäßigen Aufgaben (wie der Verarbeitung von HTTP-Anfragen von einer Website) äußerst effizient sind. Allerdings gibt es noch eine gewisse statistische Varianz bei der Aufgabenverteilung, die zu einer Überlastung mancher Recheneinheiten führen kann.

Dynamisches Bearbeiten

Im Gegensatz zu statischen Lastverteilungsalgorithmen berücksichtigen dynamische Algorithmen die aktuelle Last jeder der Recheneinheiten (auch Knoten genannt) im System. Bei diesem Ansatz können Aufgaben dynamisch von einem überlasteten Knoten zu einem unterlasteten Knoten verschoben werden, um eine schnellere Verarbeitung zu erhalten. Obwohl diese Algorithmen viel komplizierter zu entwerfen sind, können sie hervorragende Ergebnisse erzielen, insbesondere wenn die Ausführungszeit von einer Aufgabe zur anderen stark variiert.

Die Architektur des dynamischen Lastenausgleichs kann modularer sein, da kein spezieller Knoten für die Arbeitsverteilung erforderlich ist. Wenn Aufgaben einem Prozessor gemäß seinem Zustand zu einem bestimmten Zeitpunkt eindeutig zugewiesen werden, handelt es sich um eine eindeutige Zuweisung. Können die Aufgaben hingegen entsprechend dem Zustand des Systems und seiner Entwicklung permanent neu verteilt werden, spricht man von dynamischer Zuweisung. [3] Offensichtlich läuft ein Lastausgleichsalgorithmus, der zu viel Kommunikation erfordert, um seine Entscheidungen zu treffen, Gefahr, die Lösung des Gesamtproblems zu verlangsamen.

Hardwarearchitektur Bearbeiten

Heterogene Maschinen Bearbeiten

Parallel-Computing-Infrastrukturen setzen sich oft aus Einheiten unterschiedlicher Rechenleistung zusammen, die bei der Lastverteilung berücksichtigt werden sollten.

Einheiten mit geringerer Leistung können beispielsweise Anforderungen empfangen, die einen geringeren Rechenaufwand erfordern, oder im Fall homogener oder unbekannter Anforderungsgrößen weniger Anforderungen als größere Einheiten empfangen.

Gemeinsamer und verteilter Speicher Bearbeiten

Parallele Computer werden oft in zwei große Kategorien unterteilt: solche, bei denen sich alle Prozessoren einen einzigen gemeinsamen Speicher teilen, auf dem sie parallel lesen und schreiben (PRAM-Modell), und solche, bei denen jede Recheneinheit ihren eigenen Speicher hat (verteiltes Speichermodell) und bei denen Informationen werden durch Nachrichten ausgetauscht.

Bei Computern mit gemeinsam genutztem Speicher verlangsamt die Verwaltung von Schreibkonflikten die Geschwindigkeit der einzelnen Ausführung jeder Recheneinheit erheblich. Sie können jedoch perfekt parallel arbeiten. Umgekehrt kann beim Nachrichtenaustausch jeder der Prozessoren mit voller Geschwindigkeit arbeiten. Beim kollektiven Nachrichtenaustausch hingegen müssen alle Prozessoren warten, bis die langsamsten Prozessoren die Kommunikationsphase starten.

In Wirklichkeit fallen nur wenige Systeme in genau eine der Kategorien. Im Allgemeinen haben die Prozessoren jeweils einen internen Speicher, um die für die nächsten Berechnungen benötigten Daten zu speichern, und sind in aufeinanderfolgenden Clustern organisiert. Oft werden diese Verarbeitungselemente dann durch verteilten Speicher und Nachrichtenweitergabe koordiniert. Daher sollte der Lastausgleichsalgorithmus eindeutig an eine parallele Architektur angepasst sein. Andernfalls besteht die Gefahr, dass die Effizienz der parallelen Problemlösung stark reduziert wird.

Hierarchie Bearbeiten

In Anpassung an die oben gesehenen Hardwarestrukturen gibt es zwei Hauptkategorien von Lastausgleichsalgorithmen. Zum einen die, bei der Aufgaben vom „Master“ zugewiesen und von „Workern“ ausgeführt werden, die den Master über den Fortschritt ihrer Arbeit auf dem Laufenden halten, und der Master kann dann die Zuweisung oder Neuzuweisung der Arbeitslast bei dynamischen Algorithmus. In der Literatur wird dies als "Master-Worker"-Architektur bezeichnet. Andererseits kann die Kontrolle auf die verschiedenen Knoten verteilt werden. Der Lastausgleichsalgorithmus wird dann auf jedem von ihnen ausgeführt und die Verantwortung für die Zuweisung von Aufgaben (sowie die Neuzuweisung und Aufteilung nach Bedarf) wird geteilt. Die letzte Kategorie geht von einem dynamischen Lastausgleichsalgorithmus aus.

Da der Entwurf jedes Lastausgleichsalgorithmus einzigartig ist, muss die vorherige Unterscheidung qualifiziert werden. Somit ist auch eine Zwischenstrategie möglich, mit beispielsweise "Master"-Knoten für jeden Sub-Cluster, die selbst einem globalen "Master" unterliegen. Es gibt auch mehrstufige Organisationen mit einem Wechsel zwischen Master-Slave- und verteilten Steuerungsstrategien. Letztere Strategien werden schnell komplex und sind selten anzutreffen. Designer bevorzugen Algorithmen, die leichter zu kontrollieren sind.

Anpassung an größere Architekturen (Skalierbarkeit) Bearbeiten

Im Kontext von sehr langfristig laufenden Algorithmen (Server, Cloud. ) entwickelt sich die Rechnerarchitektur im Laufe der Zeit weiter. Es ist jedoch vorzuziehen, nicht jedes Mal einen neuen Algorithmus entwerfen zu müssen.

Ein äußerst wichtiger Parameter eines Lastausgleichsalgorithmus ist daher seine Anpassungsfähigkeit an eine skalierbare Hardwarearchitektur. Dies wird als Skalierbarkeit des Algorithmus bezeichnet. Ein Algorithmus wird als skalierbar für einen Eingabeparameter bezeichnet, wenn seine Leistung relativ unabhängig von der Größe dieses Parameters bleibt.

Wenn der Algorithmus in der Lage ist, sich an eine unterschiedliche Anzahl von Recheneinheiten anzupassen, die Anzahl der Recheneinheiten jedoch vor der Ausführung festgelegt werden muss, wird er als formbar bezeichnet. Wenn der Algorithmus dagegen in der Lage ist, während seiner Ausführung mit einer schwankenden Anzahl von Prozessoren umzugehen, wird der Algorithmus als formbar bezeichnet. Die meisten Lastausgleichsalgorithmen sind zumindest formbar. [4]

Fehlertoleranz Bearbeiten

Gerade in großen Rechenclustern ist es nicht tolerierbar, einen parallelen Algorithmus auszuführen, der dem Ausfall einer einzelnen Komponente nicht standhält. Daher werden fehlertolerante Algorithmen entwickelt, die Ausfälle von Prozessoren erkennen und die Berechnung wiederherstellen können. [5]

Statische Verteilung bei voller Kenntnis der Aufgaben: Präfixsumme Bearbeiten

Sind die Tasks unabhängig voneinander und lassen sich ihre jeweilige Ausführungszeit und die Tasks unterteilen, gibt es einen einfachen und optimalen Algorithmus.

Indem die Aufgaben so aufgeteilt werden, dass jedem Prozessor der gleiche Rechenaufwand zur Verfügung steht, müssen die Ergebnisse nur noch gruppiert werden. Mit einem Präfixsummenalgorithmus kann diese Division in logarithmischer Zeit in Bezug auf die Anzahl der Prozessoren berechnet werden.

Wenn die Aufgaben jedoch nicht unterteilt werden können (dh sie sind atomar), obwohl die Optimierung der Aufgabenzuweisung ein schwieriges Problem ist, ist es immer noch möglich, eine relativ faire Verteilung von Aufgaben anzunähern, vorausgesetzt, die Größe jeder von ihnen ist viel kleiner als die Gesamtberechnung, die von jedem der Knoten durchgeführt wird. [6]

Meistens ist die Ausführungszeit einer Aufgabe unbekannt und es liegen nur grobe Näherungswerte vor. Dieser Algorithmus ist zwar besonders effizient, aber für diese Szenarien nicht praktikabel.

Statische Lastverteilung ohne Vorkenntnisse Bearbeiten

Auch wenn die Ausführungszeit im Voraus gar nicht bekannt ist, ist eine statische Lastverteilung immer möglich.

Round-Robin-Planung Bearbeiten

Bei einem Round-Robin-Algorithmus wird die erste Anfrage an den ersten Server gesendet, dann die nächste an den zweiten und so weiter bis zum letzten. Dann wird es erneut gestartet, dem ersten Server die nächste Anfrage zugewiesen und so weiter.

Dieser Algorithmus kann so gewichtet werden, dass die leistungsstärksten Einheiten die größte Anzahl von Anfragen erhalten und diese zuerst erhalten.

Zufälliges statisches Bearbeiten

Beim zufälligen statischen Lastenausgleich werden einfach den verschiedenen Servern Aufgaben nach dem Zufallsprinzip zugewiesen. Diese Methode funktioniert ganz gut. Ist dagegen die Anzahl der Aufgaben im Voraus bekannt, ist es noch effizienter, eine zufällige Permutation im Voraus zu berechnen. Dies vermeidet Kommunikationskosten für jede Zuordnung. Ein Verteilungsmaster ist nicht mehr erforderlich, da jeder Bearbeiter weiß, welche Aufgabe ihm zugewiesen ist. Auch wenn die Anzahl der Tasks unbekannt ist, kann eine Kommunikation mit einer allen Prozessoren bekannten Pseudozufallszuweisungsgenerierung vermieden werden.

Die Leistung dieser Strategie (gemessen in der Gesamtausführungszeit für einen gegebenen festen Satz von Aufgaben) nimmt mit der maximalen Größe der Aufgaben ab.

Andere Bearbeiten

Natürlich gibt es auch andere Zuweisungsmethoden:

  • Weniger Arbeit: Weisen Sie den Servern mehr Aufgaben zu, indem Sie weniger ausführen (die Methode kann auch gewichtet werden).
  • Hash: ordnet Abfragen gemäß einer Hash-Tabelle zu.
  • Power of Two Choices: Wählen Sie zufällig zwei Server aus und wählen Sie die bessere der beiden Optionen. [7][8]

Meister-Arbeiter-Schema Bearbeiten

Master-Worker-Schemata gehören zu den einfachsten dynamischen Lastausgleichsalgorithmen. Ein Master verteilt die Arbeitslast auf alle Arbeiter (manchmal auch als "Slaves" bezeichnet). Zunächst sind alle Arbeiter im Leerlauf und melden dies dem Master. Der Master beantwortet Arbeiteranfragen und verteilt die Aufgaben an sie. Wenn er keine Aufgaben mehr zu erteilen hat, informiert er die Arbeiter, damit sie aufhören, nach Aufgaben zu fragen.

Der Vorteil dieses Systems besteht darin, dass es die Lasten sehr gerecht verteilt. Tatsächlich wäre die Ausführungszeit, wenn man die für die Aufgabe benötigte Zeit nicht berücksichtigt, mit der oben gezeigten Präfixsumme vergleichbar.

Das Problem dieses Algorithmus besteht darin, dass er aufgrund der hohen Menge an notwendigen Kommunikationen Schwierigkeiten hat, sich an eine große Anzahl von Prozessoren anzupassen. Dieser Mangel an Skalierbarkeit macht es in sehr großen Servern oder sehr großen parallelen Computern schnell funktionsunfähig. Der Master fungiert als Flaschenhals.

Die Qualität des Algorithmus kann jedoch stark verbessert werden, indem der Master durch eine Taskliste ersetzt wird, die von verschiedenen Prozessoren verwendet werden kann. Dieser Algorithmus ist zwar etwas schwieriger zu implementieren, verspricht aber eine deutlich bessere Skalierbarkeit, für sehr große Rechenzentren jedoch noch unzureichend.

Nicht-hierarchische Architektur, ohne Systemkenntnisse: Arbeitsklau Bearbeiten

Eine weitere Technik zur Überwindung von Skalierbarkeitsproblemen, wenn die für die Aufgabenerledigung benötigte Zeit nicht bekannt ist, ist der Arbeitsraub.

Der Ansatz besteht darin, jedem Prozessor eine bestimmte Anzahl von Aufgaben auf zufällige oder vordefinierte Weise zuzuweisen und dann inaktiven Prozessoren zu erlauben, aktiven oder überlasteten Prozessoren Arbeit zu "stehlen". Es gibt mehrere Implementierungen dieses Konzepts, die durch ein Aufgabenteilungsmodell und durch die Regeln definiert sind, die den Austausch zwischen Prozessoren bestimmen. Obwohl diese Technik besonders effektiv sein kann, ist sie schwierig zu implementieren, da sichergestellt werden muss, dass die Kommunikation nicht zur Hauptbeschäftigung der Prozessoren wird, anstatt das Problem zu lösen.

Bei atomaren Aufgaben lassen sich zwei Hauptstrategien unterscheiden, bei denen die Prozessoren mit geringer Last ihre Rechenleistung denen mit der höchsten Last anbieten, und solche, bei denen die am stärksten belasteten Einheiten die ihnen zugewiesene Arbeitslast entlasten wollen. Es hat sich gezeigt [9], dass es bei hoher Auslastung des Netzwerks für die am wenigsten belasteten Einheiten effizienter ist, ihre Verfügbarkeit anzubieten, und bei geringer Auslastung des Netzwerks sind es die überlasteten Prozessoren, die die Unterstützung der am wenigsten inaktiven Prozessoren benötigen. Diese Faustregel begrenzt die Anzahl der ausgetauschten Nachrichten.

Für den Fall, dass man von einer einzigen großen Aufgabe ausgeht, die nicht über eine atomare Ebene hinaus geteilt werden kann, gibt es einen sehr effizienten Algorithmus "Tree-Shaped Computing", [10], bei dem die Elternaufgabe in einem Arbeitsbaum verteilt wird.

Prinzip Bearbeiten

Anfangs haben viele Prozessoren eine leere Task, außer einer, die sequentiell daran arbeitet. Inaktive Prozessoren geben nach dem Zufallsprinzip Anforderungen an andere Prozessoren (nicht unbedingt aktiv). Ist dieser in der Lage, die von ihm bearbeitete Aufgabe zu unterteilen, sendet er einen Teil seiner Arbeit an den anfragenden Knoten. Andernfalls wird eine leere Aufgabe zurückgegeben. Dadurch entsteht eine Baumstruktur. Es ist dann erforderlich, ein Beendigungssignal an den Elternprozessor zu senden, wenn die Unteraufgabe abgeschlossen ist, damit dieser wiederum die Nachricht an seinen Elternprozessor sendet, bis er die Wurzel des Baums erreicht. Wenn der erste Prozessor, d. h. die Wurzel, fertig ist, kann eine globale Beendigungsnachricht gesendet werden. Am Ende ist es notwendig, die Ergebnisse zusammenzustellen, indem man den Baum zurückgeht.

Effizienz Bearbeiten

Die Effizienz eines solchen Algorithmus liegt nahe der Präfixsumme, wenn die Job-Schneide- und Kommunikationszeit im Vergleich zur zu erledigenden Arbeit nicht zu hoch ist. Um zu hohe Kommunikationskosten zu vermeiden, kann man sich eine Liste von Jobs auf Shared Memory vorstellen. Daher wird eine Anforderung auf Anforderung des Master-Prozessors einfach von einer bestimmten Position in diesem gemeinsam genutzten Speicher gelesen.

Neben der effizienten Problemlösung durch parallele Berechnungen werden Lastausgleichsalgorithmen häufig im HTTP-Anfragemanagement verwendet, wo eine Site mit einem großen Publikum in der Lage sein muss, Anfragen pro Sekunde zu verarbeiten.

Internetbasierte Dienste Bearbeiten

Eine der am häufigsten verwendeten Anwendungen des Lastenausgleichs besteht darin, einen einzelnen Internetdienst von mehreren Servern bereitzustellen, der manchmal als Serverfarm bezeichnet wird. Zu den Systemen mit häufigem Lastausgleich gehören beliebte Websites, große Internet Relay Chat-Netzwerke, FTP-Sites (File Transfer Protocol) mit hoher Bandbreite, NNTP-Server (Network News Transfer Protocol), DNS-Server (Domain Name System) und Datenbanken.

Round-Robin-DNS Bearbeiten

Round-Robin-DNS ist eine alternative Methode zum Lastenausgleich, die keinen dedizierten Software- oder Hardwareknoten erfordert. Bei dieser Technik werden mehrere IP-Adressen einem einzigen Domänennamen zugeordnet. Clients erhalten IP in einer Round-Robin-Weise. IP wird Clients mit einem kurzen Ablaufdatum zugewiesen, sodass der Client beim nächsten Zugriff auf den angeforderten Internetdienst wahrscheinlich eine andere IP verwendet.

DNS-Delegierung Bearbeiten

Eine andere effektivere Methode zum Load-Balancing mit DNS besteht darin, www.example.org als Subdomain zu delegieren, deren Zone von jedem der gleichen Server bedient wird, die die Website bedienen. Diese Technik funktioniert besonders gut, wenn einzelne Server geografisch im Internet verteilt sind. Beispielsweise:

Auf dem Server zwei dieselbe Zonendatei enthält:

Auf diese Weise antwortet sein DNS nicht, wenn ein Server ausfällt, und der Webdienst empfängt keinen Datenverkehr. Wenn die Leitung zu einem Server überlastet ist, sorgt die Unzuverlässigkeit von DNS dafür, dass weniger HTTP-Datenverkehr diesen Server erreicht. Darüber hinaus ist die schnellste DNS-Antwort an den Resolver fast immer die vom nächstgelegenen Server des Netzwerks, was einen geosensitiven Lastenausgleich gewährleistet [ Zitat benötigt ] . Eine kurze TTL auf dem A-Record hilft sicherzustellen, dass der Datenverkehr schnell umgeleitet wird, wenn ein Server ausfällt. Es muss berücksichtigt werden, dass diese Technik dazu führen kann, dass einzelne Clients mitten in der Sitzung zwischen einzelnen Servern wechseln.

Clientseitiges zufälliges Load-Balancing Bearbeiten

Ein anderer Ansatz für den Lastenausgleich besteht darin, dem Client eine Liste von Server-IPs bereitzustellen und dann den Client die IP-Adresse bei jeder Verbindung zufällig aus der Liste auswählen zu lassen. [12] [13] Dies beruht im Wesentlichen darauf, dass alle Clients ähnliche Lasten erzeugen, und das Gesetz der großen Zahlen [13], um eine einigermaßen flache Lastverteilung auf die Server zu erreichen. Es wurde behauptet, dass der clientseitige zufällige Lastausgleich tendenziell eine bessere Lastverteilung bietet als Round-Robin-DNS. Dies wurde auf Caching-Probleme mit Round-Robin-DNS zurückgeführt, die bei großen DNS-Caching-Servern dazu neigen, die Verteilung zu verzerren Round-Robin-DNS, während die clientseitige Zufallsauswahl unabhängig vom DNS-Caching unberührt bleibt. [13]

Bei diesem Ansatz kann die Methode der Zustellung der Liste von IPs an den Client variieren und kann als DNS-Liste (die ohne Round-Robin an alle Clients geliefert wird) oder durch Festcodierung in die Liste implementiert werden. Wenn ein "Smart Client" verwendet wird, der erkennt, dass ein zufällig ausgewählter Server ausgefallen ist und sich zufällig wieder verbindet, bietet er auch Fehlertoleranz.

Serverseitige Load Balancer Bearbeiten

Bei Internetdiensten ist ein serverseitiger Lastenausgleich normalerweise ein Softwareprogramm, das den Port überwacht, an dem externe Clients eine Verbindung zu den Zugriffsdiensten herstellen. Der Load Balancer leitet Anfragen an einen der "Backend"-Server weiter, der normalerweise dem Load Balancer antwortet. Dadurch kann der Load Balancer dem Client antworten, ohne dass der Client jemals von der internen Funktionstrennung weiß. Es verhindert auch, dass Clients Back-End-Server direkt kontaktieren, was Sicherheitsvorteile haben kann, indem die Struktur des internen Netzwerks verborgen wird und Angriffe auf den Netzwerk-Stack des Kernels oder nicht verwandte Dienste, die auf anderen Ports ausgeführt werden, verhindert werden.

Einige Load Balancer bieten einen Mechanismus, um etwas Besonderes zu tun, falls alle Back-End-Server nicht verfügbar sind. Dies kann die Weiterleitung an einen Backup-Load-Balancer oder die Anzeige einer Nachricht bezüglich des Ausfalls umfassen.

Wichtig ist auch, dass der Load Balancer selbst nicht zu einem Single Point of Failure wird. Normalerweise werden Load Balancer in Paaren mit hoher Verfügbarkeit implementiert, die auch Sitzungspersistenzdaten replizieren können, wenn dies von der spezifischen Anwendung erforderlich ist. [14] Bestimmte Anwendungen sind gegen dieses Problem immun programmiert, indem der Lastausgleichspunkt über differenzielle Sharing-Plattformen über das definierte Netzwerk hinaus verschoben wird. Die mit diesen Funktionen gepaarten sequentiellen Algorithmen werden durch flexible Parameter definiert, die für die spezifische Datenbank einzigartig sind. [fünfzehn]

Planungsalgorithmen Bearbeiten

Zahlreiche Scheduling-Algorithmen, auch Load-Balancing-Methoden genannt, werden von Load-Balancern verwendet, um zu bestimmen, an welchen Back-End-Server eine Anfrage gesendet werden soll. Einfache Algorithmen umfassen Zufallsauswahl, Round-Robin oder Least Connections. [16] Anspruchsvollere Load Balancer können zusätzliche Faktoren berücksichtigen, wie die gemeldete Last eines Servers, kürzeste Reaktionszeiten, Up-/Down-Status (bestimmt durch eine Überwachungsabfrage), Anzahl aktiver Verbindungen, geografischer Standort, Fähigkeiten, oder wie viel Verkehr ihm kürzlich zugewiesen wurde.

Beständigkeit Bearbeiten

Ein wichtiges Thema beim Betrieb eines Dienstes mit Lastenausgleich ist der Umgang mit Informationen, die über die mehreren Anforderungen in einer Benutzersitzung hinweg aufbewahrt werden müssen. Wenn diese Informationen lokal auf einem Back-End-Server gespeichert sind, können nachfolgende Anfragen an andere Back-End-Server sie nicht finden. Dies können zwischengespeicherte Informationen sein, die neu berechnet werden können. In diesem Fall führt der Lastausgleich einer Anforderung an einen anderen Back-End-Server nur zu einem Leistungsproblem. [16]

Im Idealfall sollte der Servercluster hinter dem Load Balancer nicht sitzungsbewusst sein, sodass die Benutzererfahrung nicht beeinträchtigt wird, wenn sich ein Client zu einem beliebigen Zeitpunkt mit einem Back-End-Server verbindet. Dies wird normalerweise mit einer gemeinsam genutzten Datenbank oder einer speicherinternen Sitzungsdatenbank wie Memcached erreicht.

Eine grundlegende Lösung für das Sitzungsdatenproblem besteht darin, alle Anforderungen in einer Benutzersitzung konsistent an denselben Back-End-Server zu senden. Dies wird als "Persistenz" oder "Klebrigkeit" bezeichnet. Ein wesentlicher Nachteil dieser Technik ist das Fehlen eines automatischen Failovers: Wenn ein Back-End-Server ausfällt, werden seine sitzungsbezogenen Informationen unzugänglich und alle davon abhängigen Sitzungen gehen verloren. Das gleiche Problem ist normalerweise für zentrale Datenbankserver relevant, auch wenn Webserver "stateless" und nicht "sticky" sind, die zentrale Datenbank ist es (siehe unten).

Die Zuweisung zu einem bestimmten Server kann auf einem Benutzernamen, einer Client-IP-Adresse basieren oder zufällig erfolgen. Aufgrund von Änderungen der wahrgenommenen Adresse des Clients aufgrund von DHCP, Netzwerkadressübersetzung und Web-Proxys kann diese Methode unzuverlässig sein. Zufällige Zuweisungen müssen vom Load Balancer gespeichert werden, was den Speicher belastet. Wenn der Load Balancer ersetzt wird oder ausfällt, können diese Informationen verloren gehen und Zuweisungen müssen möglicherweise nach einer Zeitüberschreitung oder in Zeiten hoher Auslastung gelöscht werden, um zu vermeiden, dass der für die Zuweisungstabelle verfügbare Speicherplatz überschritten wird. Die zufällige Zuweisungsmethode erfordert auch, dass Clients einen bestimmten Status beibehalten, was ein Problem darstellen kann, beispielsweise wenn ein Webbrowser das Speichern von Cookies deaktiviert hat. Ausgefeilte Load Balancer verwenden mehrere Persistenztechniken, um einige der Unzulänglichkeiten einer Methode zu vermeiden.

Eine andere Lösung besteht darin, die Daten pro Sitzung in einer Datenbank zu speichern. Im Allgemeinen ist dies schlecht für die Leistung, da es die Belastung der Datenbank erhöht: Die Datenbank wird am besten zum Speichern von Informationen verwendet, die weniger flüchtig sind als Daten pro Sitzung. Um zu verhindern, dass eine Datenbank zu einem Single Point of Failure wird, und um die Skalierbarkeit zu verbessern, wird die Datenbank häufig auf mehrere Computer repliziert, und der Lastausgleich wird verwendet, um die Abfragelast auf diese Replikate zu verteilen. Die ASP.net State Server-Technologie von Microsoft ist ein Beispiel für eine Sitzungsdatenbank. Alle Server in einer Webfarm speichern ihre Sitzungsdaten auf State Server und jeder Server in der Farm kann die Daten abrufen.

In dem sehr häufigen Fall, in dem der Client ein Webbrowser ist, besteht ein einfacher, aber effizienter Ansatz darin, die sitzungsbezogenen Daten im Browser selbst zu speichern. Eine Möglichkeit, dies zu erreichen, ist die Verwendung eines Browser-Cookies, der mit einem geeigneten Zeitstempel versehen und verschlüsselt ist. Eine andere ist das Umschreiben von URLs. Das Speichern von Sitzungsdaten auf dem Client ist im Allgemeinen die bevorzugte Lösung: Der Load Balancer kann dann einen beliebigen Backend-Server auswählen, um eine Anfrage zu bearbeiten. Diese Methode der Zustandsdatenbehandlung ist jedoch für einige komplexe Geschäftslogikszenarien schlecht geeignet, in denen die Nutzlast des Sitzungszustands groß ist und eine Neuberechnung bei jeder Anforderung auf einem Server nicht möglich ist. Das Umschreiben von URLs ist mit großen Sicherheitsproblemen verbunden, da der Endbenutzer die übermittelte URL leicht ändern und somit Sitzungsstreams ändern kann.

Noch eine andere Lösung zum Speichern persistenter Daten besteht darin, jedem Datenblock einen Namen zuzuordnen und eine verteilte Hash-Tabelle zu verwenden, um diesen Namen pseudo-zufällig einem der verfügbaren Server zuzuweisen, und dann diesen Datenblock auf dem zugewiesenen Server zu speichern.

Load-Balancer-Funktionen Bearbeiten

Hardware- und Software-Load-Balancer können eine Vielzahl von Sonderfunktionen aufweisen. Die grundlegende Funktion eines Load Balancers besteht darin, eingehende Anfragen nach einem Scheduling-Algorithmus auf mehrere Backend-Server im Cluster verteilen zu können. Die meisten der folgenden Funktionen sind herstellerspezifisch:

Asymmetrische Last Ein Verhältnis kann manuell zugewiesen werden, damit einige Back-End-Server einen größeren Anteil der Arbeitslast erhalten als andere. Dies wird manchmal als grobe Methode verwendet, um zu berücksichtigen, dass einige Server mehr Kapazität haben als andere und möglicherweise nicht immer wie gewünscht funktionieren. Prioritätsaktivierung Wenn die Anzahl der verfügbaren Server unter eine bestimmte Anzahl sinkt oder die Last zu hoch wird, können Standby-Server online geschaltet werden. TLS-Auslagerung und -Beschleunigung Die TLS-Beschleunigung (oder ihr Vorgänger SSL) ist eine Technik zum Auslagern kryptografischer Protokollberechnungen auf eine spezialisierte Hardware. Je nach Workload kann die Verarbeitung der Verschlüsselungs- und Authentifizierungsanforderungen einer TLS-Anforderung zu einem großen Teil der Anforderungen an die CPU des Webservers werden, wenn die Anforderungen steigen, werden Benutzer langsamere Antwortzeiten feststellen, da der TLS-Overhead auf die Webserver verteilt wird. Um diese Anforderung auf Webservern zu beseitigen, kann ein Balancer TLS-Verbindungen beenden und HTTPS-Anforderungen als HTTP-Anforderungen an die Webserver weiterleiten. Wird der Balancer selbst nicht überlastet, verschlechtert dies die vom Endverbraucher wahrgenommene Leistung nicht merklich. Der Nachteil dieses Ansatzes ist, dass die gesamte TLS-Verarbeitung auf einem einzigen Gerät (dem Balancer) konzentriert ist, was zu einem neuen Engpass werden kann. Einige Load-Balancer-Appliances enthalten spezielle Hardware zur Verarbeitung von TLS. Anstatt den Load Balancer zu aktualisieren, der eine ziemlich teure dedizierte Hardware ist, kann es billiger sein, auf TLS-Offload zu verzichten und ein paar Webserver hinzuzufügen. Außerdem integrieren einige Serverhersteller wie Oracle/Sun jetzt kryptografische Beschleunigungshardware in ihre CPUs wie den T2000. F5 Networks integriert eine dedizierte TLS-Beschleunigungshardwarekarte in ihren lokalen Traffic Manager (LTM), die zum Verschlüsseln und Entschlüsseln des TLS-Datenverkehrs verwendet wird. Ein klarer Vorteil des TLS-Offloading im Balancer besteht darin, dass es ihm ermöglicht, basierend auf den Daten in der HTTPS-Anforderung einen Ausgleich oder einen Inhaltswechsel durchzuführen. Schutz vor Distributed Denial of Service (DDoS)-Angriffen Load Balancer können Funktionen wie SYN-Cookies und Delayed-Binding (die Back-End-Server sehen den Client erst nach Beendigung des TCP-Handshakes) bereitstellen, um SYN-Flood-Angriffe abzuwehren und allgemein Arbeit zu entlasten von den Servern zu einer effizienteren Plattform. HTTP-Komprimierung Die HTTP-Komprimierung reduziert die zu übertragende Datenmenge für HTTP-Objekte, indem sie die in allen modernen Webbrowsern verfügbare gzip-Komprimierung verwendet. Je größer die Antwort und je weiter der Client entfernt ist, desto mehr kann diese Funktion die Antwortzeiten verbessern. Der Nachteil besteht darin, dass diese Funktion dem Load Balancer zusätzliche CPU-Belastung auferlegt und stattdessen von Webservern ausgeführt werden könnte. TCP-Offload Verschiedene Anbieter verwenden dafür unterschiedliche Begriffe, aber die Idee ist, dass normalerweise jede HTTP-Anfrage von jedem Client eine andere TCP-Verbindung ist. Diese Funktion verwendet HTTP/1.1, um mehrere HTTP-Anforderungen von mehreren Clients in einem einzigen TCP-Socket an die Back-End-Server zu konsolidieren. TCP-Pufferung Der Load Balancer kann Antworten vom Server puffern und die Daten an langsame Clients weiterleiten, sodass der Webserver einen Thread schneller für andere Aufgaben freigeben kann, als wenn er die gesamte Anfrage direkt an den Client senden müsste. Direct Server Return Eine Option für asymmetrische Lastverteilung, bei der Anforderung und Antwort unterschiedliche Netzwerkpfade haben. Integritätsprüfung Der Balancer fragt Server nach dem Zustand der Anwendungsschicht ab und entfernt ausgefallene Server aus dem Pool. HTTP-Caching Der Balancer speichert statische Inhalte, sodass einige Anfragen bearbeitet werden können, ohne die Server zu kontaktieren. Inhaltsfilterung Einige Balancer können den Datenverkehr auf dem Weg nach Belieben ändern. HTTP-Sicherheit Einige Balancer können HTTP-Fehlerseiten ausblenden, Serveridentifikationsheader aus HTTP-Antworten entfernen und Cookies verschlüsseln, damit Endbenutzer sie nicht manipulieren können. Priority Queuing Auch bekannt als Rate Shaping, die Fähigkeit, unterschiedlichem Verkehr unterschiedliche Prioritäten zu geben.Content-Aware Switching Die meisten Load-Balancer können basierend auf der angeforderten URL Anfragen an verschiedene Server senden, vorausgesetzt, die Anfrage ist nicht verschlüsselt (HTTP) oder wenn sie verschlüsselt (über HTTPS) ist, wird die HTTPS-Anfrage beim Laden beendet (entschlüsselt). Ausgleicher. Client-Authentifizierung Authentifizieren Sie Benutzer anhand einer Vielzahl von Authentifizierungsquellen, bevor Sie ihnen den Zugriff auf eine Website erlauben. Programmatische Traffic-Manipulation Mindestens ein Balancer ermöglicht die Verwendung einer Skriptsprache, um benutzerdefinierte Balancing-Methoden, willkürliche Traffic-Manipulationen und mehr zu ermöglichen. Firewall Firewalls können aus Gründen der Netzwerksicherheit direkte Verbindungen zu Back-End-Servern verhindern. Intrusion-Prevention-System Intrusion-Prevention-Systeme bieten zusätzlich zur Netzwerk-/Transportschicht durch Firewall-Sicherheit Sicherheit auf der Anwendungsebene.

Telekommunikation Bearbeiten

Der Lastausgleich kann in Anwendungen mit redundanten Kommunikationsverbindungen nützlich sein. Beispielsweise kann ein Unternehmen über mehrere Internetverbindungen verfügen, die den Netzwerkzugriff sicherstellen, wenn eine der Verbindungen ausfällt. Eine Failover-Anordnung würde bedeuten, dass ein Link für den normalen Gebrauch bestimmt ist, während der zweite Link nur verwendet wird, wenn der primäre Link ausfällt.

Durch Load-Balancing können beide Links ständig verwendet werden. Ein Gerät oder Programm überwacht die Verfügbarkeit aller Links und wählt den Pfad zum Senden von Paketen aus. Die gleichzeitige Verwendung mehrerer Links erhöht die verfügbare Bandbreite.

Shortest Path Bridging Bearbeiten

Das IEEE genehmigte den Standard IEEE 802.1aq im Mai 2012, [17] auch bekannt als Shortest Path Bridging (SPB). SPB ermöglicht es, dass alle Verbindungen über mehrere gleiche Kostenpfade aktiv sind, bietet schnellere Konvergenzzeiten, um Ausfallzeiten zu reduzieren, und vereinfacht die Verwendung von Lastausgleich in Mesh-Netzwerktopologien (teilweise verbunden und/oder vollständig verbunden), indem es dem Verkehr ermöglicht, die Last auf alle zu verteilen Pfade eines Netzwerks. [18] [19] SPB wurde entwickelt, um menschliche Fehler während der Konfiguration praktisch zu eliminieren und bewahrt die Plug-and-Play-Natur, die Ethernet als De-facto-Protokoll auf Schicht 2 etablierte. [20]

Routing 1 Bearbeiten

Viele Telekommunikationsunternehmen haben mehrere Routen durch ihre Netze oder zu externen Netzen. Sie verwenden einen ausgeklügelten Lastausgleich, um den Datenverkehr von einem Pfad auf einen anderen zu verlagern, um eine Netzwerküberlastung auf einer bestimmten Verbindung zu vermeiden und manchmal die Kosten für den Transit über externe Netzwerke zu minimieren oder die Netzwerkzuverlässigkeit zu verbessern.

Eine andere Möglichkeit, den Lastausgleich zu verwenden, sind Netzwerküberwachungsaktivitäten. Load Balancer können verwendet werden, um riesige Datenflüsse in mehrere Unterflüsse aufzuteilen und mehrere Netzwerkanalysatoren zu verwenden, die jeweils einen Teil der Originaldaten lesen. Dies ist sehr nützlich für die Überwachung schneller Netzwerke wie 10GbE oder STM64, bei denen eine komplexe Verarbeitung der Daten mit Kabelgeschwindigkeit möglicherweise nicht möglich ist. [21]

Rechenzentrumsnetzwerke Bearbeiten

Load Balancing wird häufig in Rechenzentrumsnetzwerken verwendet, um den Datenverkehr über viele vorhandene Pfade zwischen zwei beliebigen Servern zu verteilen. [22] Es ermöglicht eine effizientere Nutzung der Netzwerkbandbreite und reduziert die Bereitstellungskosten. Im Allgemeinen kann der Lastenausgleich in Rechenzentrumsnetzwerken entweder als statisch oder dynamisch klassifiziert werden.

Statisches Load-Balancing verteilt den Verkehr, indem es einen Hash der Quell- und Zieladressen und Portnummern von Verkehrsflüssen berechnet und diesen verwendet, um zu bestimmen, wie Flüsse einem der vorhandenen Pfade zugewiesen werden. Dynamischer Lastenausgleich weist Pfaden Verkehrsflüsse zu, indem die Bandbreitennutzung auf verschiedenen Pfaden überwacht wird. Die dynamische Zuweisung kann auch proaktiv oder reaktiv erfolgen. Im ersteren Fall ist die Zuweisung fest, sobald sie vorgenommen wurde, während im letzteren Fall die Netzwerklogik weiterhin verfügbare Pfade überwacht und Flüsse über diese hinweg verschiebt, wenn sich die Netzwerkauslastung ändert (bei Ankunft neuer Flüsse oder Vervollständigung vorhandener). Ein umfassender Überblick über den Lastausgleich in Rechenzentrumsnetzwerken wurde bereitgestellt. [22]


Map Suite Services Edition "Hello World"-Beispiel

Nach diesem Abschnitt können Sie mit Map Suite Services Edition eine Karte mit Ihren eigenen Daten zeichnen. Lassen Sie uns gleich zu Beginn einen Blick auf die Daten und die wichtigen Objekte werfen, die wir verwenden werden.

Shapefiles

Map Suite Services Edition 9.0 unterstützt mehrere Arten von Datenquellen, wie SQL Server 2008, Postgre, Oracle usw. Hier werden wir weitere Einführungen zu Shapefiles geben, die wir in dieser Kurzanleitung verwenden werden.

Einfach ausgedrückt, werden Shapefiles von Map Suite verwendet, um Daten bereitzustellen, die wir zum Zeichnen unserer Karte verwenden. Shapefiles speichern binäre Vektorkoordinaten, die von der Komponente verwendet werden. Sie haben eine .shp-Erweiterung. Shapefiles können auch zwei zusätzliche Dateien enthalten, die Map Suite helfen, mit den Daten zu arbeiten.

Die erste ergänzende Datei heißt .shx-Datei. Sein Zweck besteht darin, einen einfachen Index des Haupt-Shapefiles bereitzustellen. Es teilt der Map Suite-Komponente mit, wann mit dem Lesen von Binärdaten begonnen und wann gestoppt werden soll. Es ist ähnlich wie ein Verzeichnis zum Lesen der Binärdaten, eine Art Nachschlagemechanismus.

Die zweite ergänzende Datei ist die .dbf-Datei. Diese Datei enthält Tabellendaten, die dem Haupt-Shapefile zugeordnet sind. Das Shapefile kann beispielsweise die Koordinaten für eine zu zeichnende Linie enthalten, die eine Straße darstellt. Die .dbf-Datei enthält möglicherweise Informationen zum Straßennamen oder Straßentyp, z. B. Kreisstraße, Bundesstraße, Autobahn usw.

Alle drei Dateien müssen sich im selben Verzeichnis wie das Haupt-Shapefile (.shp) befinden, aber die Map Suite-Komponente erwartet nur, dass Sie den Namen und den Dateipfad des Haupt-Shapefiles angeben. Wenn wir als Nächstes Layer besprechen, werden Sie ein wenig mehr darüber verstehen, wie Karten in Map Suite unter Verwendung der Shape-Daten erstellt werden.

ShapeFileFeatureLayer

Ein ShapeFileFeaturelayer in einer Karte korreliert mit einem einzelnen Shapefile, beispielsweise einem Straßennetz. Sie können sich Layer wie echtes Gelände in der realen Welt vorstellen. Die nackte Erde kann eine Schicht sein und entweder physikalisch definierte Grenzen haben, z. B. einen Zaun um eine Militäranlage, oder gesetzliche Grenzen, z. Eine weitere Schicht darüber könnten Straßen sein, die auf der nackten Erde gebaut wurden. Es ist wichtig, dies beim Arbeiten mit Ebenen zu verstehen, da sie in der logischen Reihenfolge hinzugefügt werden müssen, die Sie erwarten, damit sie von oben richtig visualisiert werden können. Mit anderen Worten, Sie möchten keine Straßen anlegen und dann mit Erde bedecken, weil sie von Fahrzeugen nicht gesehen oder befahren werden könnten.

Wie erstellen und fügen wir Ebenen hinzu? Zunächst sollten Sie wissen, dass es drei Arten von Stilen gibt, die Ebenen darstellen. Wie oben erwähnt, folgt logischerweise, dass Sie Layer basierend auf ihrer Ansicht erstellen und hinzufügen. Daher können Sie natürlich mit einigen Polygonen beginnen, z. B. dem Umriss eines Landes und allen darin enthaltenen Regionen. Sie können dann Linien festlegen, die Flüsse und Straßen darstellen, und schließlich können Sie Punkte wie Städte oder Sehenswürdigkeiten festlegen. Denken Sie auch hier daran, dass die Logik bestimmt, was am besten funktioniert. Zum Beispiel würde das Anlegen von Straßen und dann Flüssen Flüsse auf Straßen setzen, obwohl es höchstwahrscheinlich andersherum sein sollte (die Ausnahme hier könnte ein Tunnel sein!).

MapEngine

Ein MapEngine-Objekt ist das Objekt der höchsten Ebene, das Ebenen und einige andere Objekte umfasst. Im Moment können Sie sich eine MapEngine als eine Reihe von Ebenen vorstellen, die jede Ebene rendern und Ihnen eine Karte basierend auf der anzuzeigenden Ausdehnung präsentieren können.

Stile

Shapefiles liefern die Daten, aber Stile sind die Art und Weise, wie Sie sie färben und zeichnen. Sie können die Farbe des Landes, die Breite einer Straße, die Form (Dreieck, Kreis, Kreuz usw.) eines Punktes usw. angeben.

Map Suite hat viele voreingestellte Stile integriert, einschließlich vordefinierter Stile für Straßen, Flüsse, Städte, Länder und mehr. Dies macht es einfacher, ohne großen Aufwand großartig aussehende Karten zu erstellen.

Voreingestellte Zoomstufen

Stile definieren die Art und Weise, wie wir die Daten visuell darstellen, während ZoomLevels die Situation definieren, in der wir sie anzeigen möchten. Der Grund, warum wir ZoomLevels brauchen, ist, dass wir vielleicht eine kleine Stadt anzeigen möchten, wenn wir in einen Bundesstaat hineingezoomt sind, aber wir möchten diese Stadt definitiv nicht anzeigen, wenn wir herausgezoomt sind und das gesamte Land betrachten.

Wir haben die 20 gängigsten Skalen bereitgestellt, von ZoomLevel01 bis ZoomLevel20, bei denen Sie das Aussehen Ihrer Daten möglicherweise ändern möchten. Was ist Maßstab? Die Skala gibt an, um wie viel die angegebene Fläche reduziert wurde. Wenn eine Straße in der realen Welt 10.000 Zoll lang ist und eine Karte diese Länge als 1 Zoll auf dem Bildschirm darstellt, dann sagen wir, dass der Maßstab dieser Karte 1:10.000 beträgt. Nehmen wir nun an, ZoomLevel02 verwendet einen Maßstab von 1:500 und ZoomLevel03 verwendet einen Maßstab von 1:1200. Dies bedeutet, dass die Karte mit einem aktuellen Maßstab von 1:1000 mit ZoomLevel03 übereinstimmt, dem ZoomLevel, dessen Maßstab diesem am nächsten kommt.

PresetZoomLevels hat eine sehr nützliche Eigenschaft namens ZoomLevel.ApplyUntilZoomLevel , mit der Sie ganz einfach Ihre ZoomLevels erweitern können. Nehmen wir an, Sie möchten, dass ein bestimmter Stil auf ZoomLevel03 bis ZoomLevel10 sichtbar ist. Damit das funktioniert, können wir einfach wie folgt codieren:

Map Suite Services Edition "Hello World"

Beim Erstellen unserer Beispielanwendung „Hello World“ besteht unser erster Schritt darin, einen Verweis auf den Map Suite-Arbeitsbereich ganz oben in unserem Code vor jedem anderen Code festzulegen. Wir tun dies, damit wir nicht den vollständig qualifizierten Namen der Map Suite-Klassen im gesamten Code verwenden müssen. Das Setzen eines Verweises auf den Map Suite-Arbeitsbereich kann im „Code-Behind“ des Formulars erfolgen, indem Sie das Formular auswählen und die Funktionstaste F7 drücken. Setzen Sie die Referenz wie folgt:

Sehen wir uns nun ein Codebeispiel an, um dieses Konzept zu verwirklichen. Wir werden uns Shapefiles ansehen, die sich auf die ganze Welt beziehen. In unserem Beispiel haben wir ein solches Shapefile:

(HINWEIS: Die in diesem Beispiel verwendeten Daten finden Sie im oben angehängten Beispiel im Ordner „AppData“).

Unser nächster Schritt besteht darin, unsere Ebenen zu definieren und hinzuzufügen. Hier ist der Code für unser Beispiel, das das Form1_Load-Ereignis des Formulars sowie einen Modulmember enthält.

Wenn Sie das, was Sie jetzt haben, kompilieren und ausführen, sollte Ihre Karte wie die folgende aussehen. (siehe Abbildung 3).


Abbildung 3. Eine einfache Karte von Europa.

Was ist hier also passiert? Wir haben eine Ebene erstellt und der MapEngine hinzugefügt, und die MapEngine hat sie gemäß ihren Standardstilparametern gerendert. Außerdem haben wir ZoomLevel verwendet, um die Karte so anzuzeigen, wie wir es möchten.

HINWEIS: Wie Sie im Code sehen können, verfügt MapEngine über eine sehr wichtige Methode namens DrawStaticLayers , mit der Sie die gewünschte Karte abrufen können. Es ist entscheidend, dass Sie die Längenmaßeinheit der Karte bei dieser Methode richtig einstellen, da Shapefiles nur binäre Vektorkoordinaten speichern (die in Dezimalgrad, Fuß usw. sein können) und unsere MapEngine keine Ahnung hat, was die Einheit ist, bis wir explizit setzen. Informationen zur zu verwendenden Maßeinheit finden Sie normalerweise irgendwo in der Shapefile-Dokumentation oder in der ergänzenden Datendatei.

Das war einfach, oder? Fügen wir dem Beispiel ein weiteres Shapefile hinzu, sodass wir insgesamt zwei Ebenen haben:

Das Ergebnis ist wie folgt (Abbildung 4):


Abbildung 4. Europakarte mit 2 Ebenen.


Warum Azure Load Balancer verwenden?

Mit Azure Load Balancer können Sie Ihre Anwendungen skalieren und hochverfügbare Dienste erstellen. Load Balancer unterstützt sowohl eingehende als auch ausgehende Szenarien. Load Balancer bietet geringe Latenz und hohen Durchsatz und lässt sich auf Millionen von Datenflüssen für alle TCP- und UDP-Anwendungen skalieren.

Zu den wichtigsten Szenarien, die Sie mit Azure Standard Load Balancer ausführen können, gehören:

Lastausgleich intern und extern Datenverkehr zu virtuellen Azure-Computern.

Erhöhen Sie die Verfügbarkeit durch die Verteilung von Ressourcen innerhalb und über Zonen.

Konfigurieren ausgehende Konnektivität für virtuelle Azure-Computer.

Benutzen Gesundheitssonden um Ressourcen mit Lastenausgleich zu überwachen.

Beschäftigen Port-Weiterleitung um über eine öffentliche IP-Adresse und einen Port auf virtuelle Maschinen in einem virtuellen Netzwerk zuzugreifen.

Unterstützung aktivieren für Lastverteilung von IPv6.

Der Standard-Load Balancer bietet mehrdimensionale Metriken über Azure Monitor. Diese Messwerte können für eine bestimmte Dimension gefiltert, gruppiert und aufgeschlüsselt werden. Sie bieten aktuelle und historische Einblicke in die Leistung und den Zustand Ihres Dienstes. Insights for Azure Load Balancer bietet ein vorkonfiguriertes Dashboard mit nützlichen Visualisierungen für diese Metriken. Ressourcengesundheit wird ebenfalls unterstützt. Rezension Standard-Load-Balancer-Diagnose für mehr Details.

Bewegung intern und extern Load Balancer-Ressourcen in allen Azure-Regionen.

Lastenausgleich für TCP- und UDP-Fluss auf allen Ports gleichzeitig mit HA-Ports.

Standardmäßig sicher

Der Standard-Load-Balancer basiert auf dem Zero-Trust-Netzwerksicherheitsmodell.

Standard Load Balancer ist standardmäßig sicher und Teil Ihres virtuellen Netzwerks. Das virtuelle Netzwerk ist ein privates und isoliertes Netzwerk.

Standard-Load-Balancer und öffentliche Standard-IP-Adressen werden für eingehende Verbindungen geschlossen, es sei denn, sie werden von Netzwerksicherheitsgruppen geöffnet. NSGs werden verwendet, um erlaubten Datenverkehr explizit zuzulassen. Wenn Sie keine NSG in einem Subnetz oder einer NIC Ihrer virtuellen Computerressource haben, darf der Datenverkehr diese Ressource nicht erreichen. Informationen zu NSGs und deren Anwendung in Ihrem Szenario finden Sie unter Netzwerksicherheitsgruppen.

Der Basic Load Balancer ist standardmäßig für das Internet geöffnet.

Load Balancer speichert keine Kundendaten.


9 Antworten 9

Ich kopiere die Dateien die ganze Zeit, wie Sie es vorgeschlagen haben, und es ist in Ordnung. Alle Dateien, die nicht übereinstimmen, werden normalerweise von Steam erneut heruntergeladen, weshalb sie nach einer neuen Kopie immer noch ein wenig aktualisiert werden. Wenn Sie nicht möchten, dass alle nur die Sounds und Karten (die den meisten Platz beanspruchen) erneut herunterladen, können Sie einfach die .gcf-Dateien für jedes Spiel aus Program Files/Steam/SteamApps nehmen.

Steam hat auch eine "Backup"-Funktion, die Sie verwenden können. Die erstellten Dateien können von PC zu PC verschoben und auf jedem wiederhergestellt werden.

Hier ist die offizielle Antwort von Valve, wie man den Ort verlagert, an dem Steam-Spiele installiert sind. Während der Artikel so geschrieben ist, als ob Sie auf demselben Computer von einem Verzeichnis in ein anderes wechseln würden, sind die Prinzipien für das Verschieben von heruntergeladenen Inhalten von einem Computer auf einen anderen gleich:

Eine inoffizielle ist zu kopiere nur deinen kompletten Steam-Ordner auf einen anderen PC/HDD, ohne Steam neu installieren zu müssen.

Ich habe es viele Male gemacht und es funktioniert auch auf einer externen Festplatte, das ist einfach, wenn Sie Ihren Freunden einige Spiele zeigen möchten, wenn Sie Ihren PC nicht dabei haben.

Installieren Sie Steam, kopieren Sie dann einfach die Verzeichnisse auf den neuen Computer, verwenden Sie die gleichen Dateipfade usw.

Und Sie müssen die Datei clientregistry.blob löschen, die Sie von Ihrem alten Computer kopiert haben. Keine Sorge, Steam erstellt ein neues, wenn Sie es auf Ihrem neuen Computer ausführen.

Oder laden Sie die Spiele nach der Installation von Steam erneut herunter

Laden Sie Steam Mover von der Techmixer-Site herunter:

Sie können die Informationen zuerst überprüfen.

Es wurde von einem Steam-Benutzer geschrieben und zuerst im Valve-Entwicklerforum veröffentlicht.

Es ermöglicht eine einfache Übertragung zwischen separaten Ordnern und/oder Festplatten und ist kostenlos und portabel.

Dazu gibt es 2 Möglichkeiten.

  1. Erstellen Sie ein Backup von Dota 2 über die Steam-Backup- und Wiederherstellungsfunktion, die Sie auf der Registerkarte "Steam" finden.
  2. Kopieren Sie diese auf einen neuen Computer.
  3. Installieren Sie Steam, melden Sie sich bei Ihrem Steam-Konto an. Alle Spiele (einschließlich Dota 2) werden in Ihrer Spielebibliothek angezeigt. Installieren Sie Dota 2 über ein Backup, das Sie in Schritt 4 erstellt haben. Nachdem die Installation abgeschlossen ist, aktualisieren Sie das Spiel "MAY", um alle fehlenden oder veralteten Dateien herunterzuladen.
  1. Kopieren Sie den Ordner „common“ und „appmanifest_570.acf“ von PC 1 auf eine Festplatte oder einen USB-Stick. Dieses Zeug befindet sich im Steamapp-Ordner. Am häufigsten lautet die Adresse C:Program Files(x86)Steamsteamapps
  2. Gehen Sie nun zu PC 2 und installieren Sie Steam.
  3. Sobald Steam auf PC 2 installiert ist, schließen Sie es vollständig und fügen Sie diese kopierten Ordner „common“ und „appmanifest_570.acf“ in den Ordner steamapp auf PC 2 ein.
  4. Sobald dieser Vorgang abgeschlossen ist, können Sie Dota 2 auch auf PC 2 spielen.

Welche Methode Sie auch wählen, ich schlage vor, dass Sie den Cache des Spiels validieren, bevor Sie das Spiel starten. Sie können dies tun, indem Sie in Dota 2-Eigenschaften >> Registerkarte Lokale Dateien >> Integrität des Spiel-Cache überprüfen.

Wenn Sie auf ein Problem oder einen Fehler stoßen, enthält dieser Beitrag das vollständige Verfahren mit Bildern und eine Anleitung zur Fehlerbehebung.

Sie sollten sicher sein, die Spieldateien einfach zu kopieren - aber sollte es noch schlimmer kommen, können Sie einfach so oft neu herunterladen, wie Sie möchten. (Das mache ich immer.)

Nachdem ich alle Antworten gelesen habe, glaube ich, dass ich eine einzigartige Situation hatte, in der ich bereits mit dem Herunterladen des Spiels begonnen hatte. Versuche, das Spiel zu kopieren, hatten immer noch Dampf und dachten, es sollte heruntergeladen werden.

Hier ist also eine Liste von Schritten, die meiner Meinung nach die anderen Antworten und meine Situation enthält. Wenn ich das durchziehe, bezeichne ich das Zeug als Quelle und Ziel. Ziel ist der PC oder die Dateien, auf die Sie die Spiele kopieren möchten.

Öffnen Sie Steam auf dem Ziel-PC.

Zuerst sollten wir sicherstellen, dass sich das Spiel nicht aufgrund eines gestarteten Downloads auf dem Ziel-PC befindet. Klicken Sie mit der rechten Maustaste auf das Spiel / Eigenschaften / Lokale Dateien, und wenn die Schaltfläche "Lokale Spielinhalte löschen" aktiviert ist, klicken Sie darauf und führen Sie diesen Vorgang aus. Das Spiel sollte immer noch in Ihrer Bibliothek aufgeführt sein, jetzt nur ausgegraut.

Schließen Sie Steam auf dem Ziel-PC. Stellen Sie sicher, dass es nicht geöffnet ist. (Ich glaube nicht, dass dies erforderlich ist, aber nur für den Fall).

Vom Quell-PC, entweder über das Netzwerk oder mit USB-Sticks etc. Kopieren Sie den Spielordner vom Quell-PC aus einem Ordner ähnlich diesem C:Program Files (x86)SteamSteamAppscommon an den ähnlichen Ort auf dem Ziel Stk.

Sobald die Kopie fertig ist. Öffnen Sie Steam auf dem Ziel-PC, klicken Sie mit der rechten Maustaste auf das Spiel in Ihrer Bibliothek und klicken Sie auf Installieren.


11 Antworten 11

Das Quellbaum-Layout sollte die Architektur als Folgerung widerspiegeln, eine gut strukturierte Architektur kann zu einem gut strukturierten Quellbaum-Layout führen. Ich schlage vor, sich über das POSA1-Schichtenmuster zu informieren, zu versuchen, Ihre Architektur in eine Schichtstruktur einzupassen, dann jede der resultierenden Schichten zu benennen und diese als Grundlage für Ihre Quellhierarchie zu verwenden. Ausgehend von einer gemeinsamen dreistufigen Architektur:

  • Präsentation/WebService (Präsentieren einer Web-Service-Schnittstelle zu unserer Geschäftslogik)
  • Logik/* (Geschäftslogik-Module gehen hier rein)
  • storage/sql (Backend-Speicher-APIs hier - dies verwendet eine SQL-Schnittstelle zum Speichern in einer Datenbank)
  • util/* (Utility-Code - von allen anderen Layern verwendbar, aber das bezieht sich nicht außerhalb von util, geht hier)

Beachten Sie, dass die Ebenen keinen Code direkt enthalten, sondern ausschließlich zum Organisieren von Modulen verwendet werden.

Innerhalb eines Moduls verwende ich die folgende Art von Layout:

  • <module> (Pfad zum Modul definiert direkt die modulare Schnittstelle)
  • <module>/impl/<implName> (eine spezifische Implementierung der modularen Schnittstelle)
  • <module>/doc (Dokumentation zur Verwendung des Moduls)
  • <module>/tb (Unit-Test-Code für das Modul)

wo sich das <module> im Repository befindet, entsprechend der Schicht, zu der es gehört.

Ich kann Ihnen nicht wirklich viele Ratschläge zu Webprojekten geben, aber so strukturiere ich meinen Baum in einem Programmierprojekt (hauptsächlich aus einer C/C++-Perspektive):

  • /
    • src &mdash Von mir selbst geschriebene Quelldateien
    • ext &mdash Enthält Bibliotheken von Drittanbietern
      • libname-1.2.8
        • einschließen &mdash-Header
        • lib &mdash Kompilierte Bibliotheksdateien
        • Donwload.txt &mdash Enthält Link zum Herunterladen der verwendeten Version
        • vc10 &ndash Ich ordne Projektdateien je nach IDE

        Wenn ich eine Bibliothek schreibe (und C/C++ verwende), organisiere ich meine Quelldateien zuerst in zwei Ordnern namens "include" und "src" und dann nach Modul. Wenn es sich um eine Anwendung handelt, werde ich sie nur nach Modulen organisieren (Header und Quellen werden in denselben Ordner verschoben).

        Dateien und Verzeichnisse, die ich oben aufgelistet habe in Kursivschrift Ich werde dem Code-Repository nichts hinzufügen.

        Das Maven-Standardverzeichnislayout ist spezifisch für Java, kann aber auch als gute Grundlage für andere Arten von Projekten dienen.

        Hier ist die Grundstruktur (Sie könnten die Java-Verzeichnisse durch php , cpp usw. ersetzen):

        Die Struktur gliedert sich im Wesentlichen in src/main und src/test, die dann nach Typ gruppiert werden.

        Im Idealfall verfügt die Organisation über ein einziges Repository, dessen Struktur darauf abzielt, das Engagement zwischen Engineering und Business zu erhöhen und die Wiederverwendung zu fördern.

        Ein Ordner pro Produkt hilft zu kommunizieren, wie die Software das Geschäft unterstützt.

        Im Idealfall ist jedes "Produkt" wenig mehr als eine Konfigurationsdatei, die angibt, welches Systeme aufrufen und wie sie zu konfigurieren sind. Der doc-Unterordner könnte die oberste Ebene der KurzbeschreibungSpezifikation und jegliches Werbematerial usw. enthalten.

        Durch die Trennung von Produkten und Systemen kommunizieren wir das Potenzial der Wiederverwendung an die kundenseitige Seite des Unternehmens und brechen einzelne Produktsilos auf. (Dies steht im Gegensatz zum "Produktlinien"-Ansatz für das gleiche Problem)

        Ein Ordner pro System hilft dabei, die primären Fähigkeiten und Chancen/Werte des Inhalts des Repositorys zu kommunizieren.

        1. "Konfigurationsmanagement"-Dateien, die Build- und Bereitstellungsumgebungen angeben.
        2. Testkonfiguration auf Systemebene (könnte eine erhebliche Menge sein).
        3. Top-Level-Logik und -Funktionalität, die meisten Schwerstarbeit wird von Bibliotheksfunktionen erledigt.

        Wiederverwendbare Komponenten, die von verschiedenen Systemen aufgerufen werden. Die meisten Entwicklungsaktivitäten sind eher um die Produktion von Bibliotheken als um Systeme herum organisiert, sodass die Wiederverwendung in den Entwicklungsprozess "eingebrannt" wird.

        Build, Continuous Integration und andere Entwicklungsautomatisierungsfunktionen.

        Der Quellbaum ist ein wichtiges Dokument und prägt den Ansatz, die Struktur und die Psychologie der Geschäftsbeziehung mit seiner proprietären Technologie.

        Ich kenne mich mit Konventionen nicht wirklich aus, aber alle meine Hauptprojekte werden mit Symfony Framework erstellt und ich habe mich an eine Baumstruktur wie folgt gewöhnt:

        • Apps
        • App Name
          • config (App-spezifische Konfigurationsdateien)
          • lib (App-spezifische PHP-Dateien)
          • Module (modulare Verteilung der Funktionalität)
            • Modulname
              • Vorlagen (html)
              • Aktionen (php-Code)
              • Base
              • base (Basisformklassen)
              • Bilder
              • Datei.css

              Bei Interesse lesen Sie bitte die Symfony-Dokumentation zu diesem Thema für weitere Anfragen (MVC und Code Organization auf Symfony).

              Was ich für jedes Projekt versuche, ist ähnlich wie:

              • src - Quelldateien, ein Ordner für jeden Namespace/Paket zum einfachen Abrufen von Dateien (sogar Header-Dateien für C/C++)
              • ext - Für Externals/Drittanbieter-Bibliotheken ist es einfach, Externals (wie SVN-Repositorys) hinzuzufügen. Im Inneren ein Ordner für jede Bibliothek (Binärdateien und Include-Dateien)
              • Behälter - für erstellte Binärdateien können schnell zur Veröffentlichung exportiert werden
                • inc - für C/C++-Header-Datei (kopiert von IDE/makefile/etc.)
                • Konfiguration - für einige Konfigurationsdateien
                • ziehfähig - für einige Bilder oder Symbole

                Alle Dateien oder Makefiles der IDE werden direkt im Stammverzeichnis gespeichert, wenn Sie nur eine davon verwenden.

                Meine Empfehlung ist, eine Vielzahl von Frameworks oder Engines herunterzuladen und zu sehen, wie riesige Entwicklungsteams mit ihrem Ordnerlayout umgegangen sind.

                Es gibt so viele Möglichkeiten, Dateien zu organisieren, dass es besser ist, eine auszuwählen und zu versuchen, bei einem bestimmten Projekt dabei zu bleiben. Halten Sie sich bis zur Fertigstellung oder Überarbeitung an eine bestimmte Konvention, um Fehler zu vermeiden und unnötige Zeit zu verlieren.

                Sie können Laravel-, Symphony- oder Codeigniter-Frameworks für Webprojekte herunterladen, um ein sofort funktionierendes Ordnerlayout zu erhalten.

                Ich werde also versuchen, ein für jede Entwicklung übliches Ordnerlayout zu vermitteln:

                MVC (Model View Controller) bietet ein gutes Organisationsparadigma.

                Root-Quellcode könnte sein src (C++) oder App (Web Entwicklung)

                Eine Dateistruktur, die kein klares Ziel für die Klassen hat, die sie gruppiert, wird definitiv Verwirrung stiften. Es dient nicht nur zum Organisieren von Code, sondern kann auch Autoloader, Class Factory, Wrap Local Storage, Remote Storage und Namespace unterstützen.

                Diese Ordnerstruktur ist abgeleitet und vereinfacht von Laravel-Framework. Ich bevorzuge in diesem Beitrag die Pluralbezeichnung, aber ich verwende in meinen Projekten singuläre Wörter.

                src/speicher (models/file-storage/api/mysql/sql-lite/memcached/redis-Implementierungen)

                src/repositories (Ein Wrapper von 'Speicherimplementierungen' mit etwas Speicherlogik, einer gemeinsamen Schnittstelle und einer Konvention für die Rückgabe von Ergebnissen.)

                src/services | Logik | Entitäten (App-Geschäftslogik)

                src/controller (Wird in der Webentwicklung verwendet, um Serveranfragen an Ihre Dienste weiterzuleiten)

                src/module | Systeme (Modulare Systeme, die die allgemeine Funktionalität Ihres Frameworks erweitern. Dienste können Module verwenden, aber nicht umgekehrt)

                src/Helfer (Hilfs- oder Wrapper-Klassen wie zB String-Manipulation. Oftmals könnte dies auf libs|vendor bei Drittanbietern sein)

                src/typen (Benannte Aufzählungen)

                öffentlich | bauen | Ausgabe (Web oder c++)

                Konfiguration (Setup-Dateien. YAML wird für plattformübergreifende Konfigurationsdateien immer beliebter)

                lang (de/es/ru/. )

                Bootstrap (Startet das Framework und die App)

                Dokumente (Dokumentation im Markdown-Format .md geschrieben)

                Tests (Einheitenprüfung)

                Datenbank/Migrationen (Datenbankstruktur von Grund auf neu erstellen)

                Datenbank/Seeds (Füllt Ihre Datenbank mit Dummy-Daten zum Testen)

                Bibliotheken | Verkäufer (alle Software von Drittanbietern. 'libs' auf C++ und 'vendor' normalerweise auf php)

                Vermögenswerte | Ressourcen (Bilder/Sounds/Skripte/json/beliebige Medien)


                7 R Sonstiges

                7.1 Wie kann ich Komponenten einer Liste auf NULL setzen?

                um Komponente i der Liste x auf NULL zu setzen, ähnlich für benannte Komponenten. Setzen Sie x[i] oder x[[i]] nicht auf NULL , da dies die entsprechende Komponente aus der Liste entfernt.

                Um die Zeilennamen einer Matrix x zu löschen, kann es einfacher sein, rownames(x) <-NULL zu verwenden, ähnlich für Spaltennamen.

                7.2 Wie kann ich meinen Arbeitsbereich speichern?

                save.image() speichert die Objekte im Benutzer .GlobalEnv in der Datei .RData im R-Startverzeichnis. (Dies geschieht auch nach q("yes") .) Mit save.image( file ) kann man das Bild unter einem anderen Namen speichern.

                7.3 Wie kann ich meinen Arbeitsbereich aufräumen?

                Um alle Objekte in der derzeit aktiven Umgebung (normalerweise .GlobalEnv ) zu entfernen, können Sie Folgendes tun:

                (Ohne all = TRUE werden nur die Objekte entfernt, deren Namen nicht mit &lsquo . &rsquo beginnen.)

                7.4 Wie kann ich eval() und D() zum Laufen bringen?

                Seltsame Dinge passieren, wenn Sie eval(print(x), envir = e) oder D(x^2, "x") verwenden. Der erste sagt Ihnen entweder, dass " x " nicht gefunden wurde, oder gibt den Wert des falschen x aus. Der andere wird wahrscheinlich Null zurückgeben, wenn x existiert, andernfalls einen Fehler.

                Dies liegt daran, dass in beiden Fällen das erste Argument zuerst in der aufrufenden Umgebung ausgewertet wird. Das Ergebnis (das ein Objekt des Modus "expression" oder "call" sein sollte) wird dann ausgewertet oder differenziert. Was Sie (höchstwahrscheinlich) wirklich wollen, erhalten Sie, indem Sie das erste Argument &ldquoquotieren&rdquo, wenn Sie es mit expression() umgeben. Beispielsweise,

                Obwohl dieses Verhalten zunächst etwas seltsam erscheinen mag, ist es vollkommen logisch. Das &ldquointuitive&rdquo-Verhalten könnte leicht implementiert werden, aber es würden Probleme auftreten, wenn der Ausdruck in einer Variablen enthalten ist, als Parameter übergeben wird oder das Ergebnis eines Funktionsaufrufs ist. Betrachten Sie zum Beispiel die Semantik in Fällen wie

                Weitere Beispiele finden Sie auf der Hilfeseite für deriv().

                7.5 Warum verlieren meine Matrizen Dimensionen?

                Wenn eine Matrix mit einer einzelnen Zeile oder Spalte durch eine Subskriptionsoperation erzeugt wird, z. B. Zeile <-mat[2, ] , wird sie standardmäßig in einen Vektor umgewandelt. Wenn ein Array mit einer Dimension von beispielsweise 2 x 3 x 1 x 4 durch Subskription erstellt wird, wird es in ähnlicher Weise in ein 2 x 3 x 4 Array umgewandelt, wobei die unnötige Dimension verloren geht. Nach vielen Diskussionen wurde festgestellt, dass dies ein Feature.

                Um dies zu verhindern, fügen Sie der Subskription die Option drop = FALSE hinzu. Beispielsweise,

                Die Option drop = FALSE sollte beim Programmieren defensiv verwendet werden. Zum Beispiel die Aussage

                gibt einen Vektor anstelle einer Matrix zurück, wenn der Index die Länge 1 hat, was später im Code zu Fehlern führt. Es sollte wahrscheinlich umgeschrieben werden als

                7.6 Wie funktioniert das automatische Laden?

                R hat eine spezielle Umgebung namens .AutoloadEnv . Die Verwendung von autoload( name , pkg ) , wobei name und pkg Strings sind, die die Namen eines Objekts und des Pakets angeben, das es enthält, speichert einige Informationen in dieser Umgebung. Wenn R versucht, name auszuwerten, lädt es das entsprechende Paket pkg und wertet name in der neuen Paketumgebung neu aus.

                Mit diesem Mechanismus verhält sich R so, als ob das Paket geladen wäre, belegt aber (noch) keinen Speicher.

                Ein sehr schönes Beispiel finden Sie auf der Hilfeseite für autoload().

                7.7 Wie sollte ich Optionen einstellen?

                Die Funktion options() erlaubt das Setzen und Untersuchen einer Vielzahl von globalen &ldquooptions&rdquo, die die Art und Weise beeinflussen, wie R seine Ergebnisse berechnet und anzeigt. Die Variable .Options enthält die aktuellen Werte dieser Optionen, sollte aber niemals direkt zugewiesen werden, es sei denn, Sie wollen sich verrückt machen&mdash einfach so tun, als ob es sich um eine &ldquo-only&rdquo Variable handelt.

                Was wirklich verwendet wird, ist die global Wert von .Options , und die Verwendung von options(OPT = VAL) aktualisiert ihn korrekt. Lokale Kopien von .Options , entweder in .GlobalEnv oder in einer Funktionsumgebung (Frame), werden einfach stillschweigend ignoriert.

                7.8 Wie funktionieren Dateinamen in Windows?

                Da R Zeichenfolgenbehandlung im C-Stil verwendet, wird &lsquo &rsquo als Escape-Zeichen behandelt, sodass man beispielsweise einen Zeilenumbruch als &lsquo &rsquo eingeben kann. Wenn Sie wirklich ein &lsquo &rsquo brauchen, müssen Sie ihm mit einem anderen &lsquo &rsquo entkommen.

                Verwenden Sie daher in Dateinamen etwas wie "c:datamoney.dat" . Sie können auch &lsquo &rsquo durch &lsquo / &rsquo ( "c:/data/money.dat" ) ersetzen.

                7.9 Warum gibt es beim Plotten einen Farbzuordnungsfehler?

                Auf einem X11-Gerät führt das Plotten manchmal, z. B. beim Ausführen von demo("image") , zu &ldquoError: Farbzuordnungsfehler&rdquo. Dies ist ein X-Problem und nur indirekt mit R verbunden. Es tritt auf, wenn Anwendungen, die vor R gestartet wurden, alle verfügbaren Farben verwendet haben. (Wie viele Farben verfügbar sind, hängt von der X-Konfiguration ab, manchmal können nur 256 Farben verwendet werden.)

                Eine Anwendung, die dafür bekannt ist, Farben zu „Essen” ist Netscape. Wenn das Problem auftritt, während Netscape ausgeführt wird, versuchen Sie, es mit der Option -no-install (um die Standard-Colormap zu verwenden) oder -install (um eine private Colormap zu installieren) (neu) zu starten.

                Sie können den Farbtyp von X11() auch auf "pseudo.cube" anstelle des standardmäßigen "pseudo" setzen. Weitere Informationen finden Sie auf der Hilfeseite für X11().

                7.10 Wie wandle ich Faktoren in Zahlen um?

                Es kann vorkommen, dass beim Einlesen numerischer Daten in R (normalerweise beim Einlesen einer Datei) diese als Faktoren eingehen. Wenn f ein solches Faktorobjekt ist, können Sie

                um die Zahlen zurückzubekommen. Effizienter, aber schwerer zu merken, ist

                Rufen Sie auf keinen Fall as.numeric() oder ähnliches direkt für die vorliegende Aufgabe auf (da as.numeric() oder unclass() die internen Codes liefern).

                7.11 Sind Trellis-Anzeigen in R implementiert?

                Das empfohlene Paket Gitter (basierend auf Basispaket Gitter) bietet grafische Funktionen, die mit den meisten Trellis-Befehlen kompatibel sind.

                Sie könnten sich auch coplot() und dotchart() ansehen, die zumindest einiges von dem tun könnten, was Sie wollen. Beachten Sie auch, dass die R-Version von pairs() ziemlich allgemein ist und die meisten Funktionen von splom() bietet und dass die Standard-Plot-Methode von R&rsquo über ein Argument asp verfügt, das es ermöglicht, das Seitenverhältnis des Plots anzugeben (und gegen die Größenänderung des Geräts zu korrigieren). .

                (Da das Wort &ldquoTrellis&rdquo als Marke beansprucht wurde, verwenden wir es nicht in R. Der Name &ldquolattice&rdquo wurde für das R-Äquivalent gewählt.)

                7.12 Was sind die umgebenden und übergeordneten Umgebungen?

                Innerhalb einer Funktion möchten Sie möglicherweise auf Variablen in zwei zusätzlichen Umgebungen zugreifen: in der Umgebung, in der die Funktion definiert wurde (&ldquoenclosing&rdquo) und in der, in der sie aufgerufen wurde (&ldquoparent&rdquo).

                Wenn Sie eine Funktion an der Befehlszeile erstellen oder in ein Paket laden, ist ihre umgebende Umgebung der globale Arbeitsbereich. Wenn Sie eine Funktion f() innerhalb einer anderen Funktion g() definieren, ist ihre umgebende Umgebung die Umgebung innerhalb von g() . Die einschließende Umgebung für eine Funktion wird beim Erstellen der Funktion festgelegt. Sie können die umgebende Umgebung für eine Funktion f() mithilfe von environment(f) herausfinden.

                Die &ldquoparent&rdquo-Umgebung hingegen wird beim Aufrufen einer Funktion definiert. Wenn Sie lm() in der Befehlszeile aufrufen, ist seine übergeordnete Umgebung der globale Arbeitsbereich, wenn Sie es innerhalb einer Funktion f() aufrufen, ist seine übergeordnete Umgebung die Umgebung in f() . Sie können die übergeordnete Umgebung für einen Funktionsaufruf ermitteln, indem Sie parent.frame() oder sys.frame(sys.parent()) verwenden.

                Für die meisten für den Benutzer sichtbaren Funktionen ist die umgebende Umgebung also der globale Arbeitsbereich, da dort die meisten Funktionen definiert werden. Die übergeordnete Umgebung befindet sich dort, wo die Funktion zufällig aufgerufen wird. Wenn eine Funktion f() innerhalb einer anderen Funktion g() definiert ist, wird sie wahrscheinlich auch innerhalb von g() verwendet, sodass ihre Elternumgebung und die umgebende Umgebung wahrscheinlich identisch sind.

                Übergeordnete Umgebungen sind wichtig, da Dinge wie Modellformeln in der Umgebung ausgewertet werden müssen, aus der die Funktion aufgerufen wurde, da dort alle Variablen verfügbar sind. Dies beruht darauf, dass die Elternumgebung bei jedem Aufruf potenziell unterschiedlich ist.

                Einschließende Umgebungen sind wichtig, da eine Funktion Variablen in der einschließenden Umgebung verwenden kann, um Informationen mit anderen Funktionen oder mit anderen Aufrufen ihrer selbst auszutauschen (siehe Abschnitt über lexikalischen Bereich). Dies beruht darauf, dass die umgebende Umgebung bei jedem Aufruf der Funktion dieselbe ist. (In C würde dies mit statischen Variablen geschehen.)

                Umfang ist schwer. Das Betrachten von Beispielen hilft. Es ist besonders aufschlussreich, sich Beispiele anzuschauen, die in R und S unterschiedlich funktionieren, und zu versuchen herauszufinden, warum sie sich unterscheiden. Eine Möglichkeit, die Scoping-Unterschiede zwischen R und S zu beschreiben, besteht darin, dass in S die umgebende Umgebung immer der globale Arbeitsbereich, aber in R befindet sich die umgebende Umgebung dort, wo die Funktion erstellt wurde.

                7.13 Wie kann ich ein Plot-Label ersetzen?

                Oftmals ist es erwünscht, den Wert eines R-Objekts in einem Plotlabel, z. B. einem Titel, zu verwenden. Dies wird leicht mit paste() erreicht, wenn das Label eine einfache Zeichenkette ist, aber nicht immer offensichtlich, wenn es sich bei dem Label um einen Ausdruck handelt (für eine verfeinerte mathematische Annotation). Verwenden Sie in einem solchen Fall entweder parse() für Ihre eingefügte Zeichenkette oder verwenden Sie replace() für einen Ausdruck. Wenn beispielsweise ahat ein Schätzer Ihres Parameters ist ein von Interesse, verwenden

                (Beachten Sie, dass es &lsquo == &rsquo und nicht &lsquo = &rsquo ist). Manchmal gibt bquote() eine kompaktere Form, z.B.

                wobei in &lsquo .() &rsquo eingeschlossene Unterausdrücke durch ihre Werte ersetzt werden.

                Weitere Beispiele finden Sie in den Mailinglisten-Archiven.

                7.14 Was sind gültige Namen?

                Beim Erstellen von Datenrahmen mit data.frame() oder read.table() stellt R standardmäßig sicher, dass die Variablennamen syntaktisch gültig sind. (Das Argument check.names dieser Funktionen steuert, ob Variablennamen überprüft und bei Bedarf von make.names() angepasst werden.)

                Um zu verstehen, was Namen &ldquovalid&rdquo sind, muss man berücksichtigen, dass der Begriff &ldquoname&rdquo in der Sprache auf verschiedene (aber verwandte) Arten verwendet wird:

                1. EIN syntaktischer Name ist eine Zeichenfolge, die der Parser als diesen Ausdruckstyp interpretiert. Es besteht aus Buchstaben, Zahlen und dem Punkt und (für Versionen von R mindestens 1.9.0) Unterstrichen und beginnt entweder mit einem Buchstaben oder einem Punkt ohne gefolgt von einer Zahl. Reservierte Wörter sind keine syntaktischen Namen.
                2. Ein Objektname ist eine Zeichenfolge, die einem Objekt zugeordnet ist, das in einem Ausdruck entweder durch den Objektnamen links von einer Zuweisungsoperation oder als Argument für die Funktion Assign() zugewiesen wird. Es ist normalerweise auch ein syntaktischer Name, kann aber ein beliebiger nicht leerer String sein, wenn er in Anführungszeichen gesetzt wird (und er wird immer in Anführungszeichen von Assign() angegeben).
                3. Ein Argumentname ist das, was links vom Gleichheitszeichen erscheint, wenn ein Argument in einem Funktionsaufruf angegeben wird (z. B. f(trim=.5) ). Argumentnamen sind normalerweise auch syntaktische Namen, können aber wieder alles sein, wenn sie in Anführungszeichen stehen.
                4. Ein Elementname ist ein String, der einen Teil eines Objekts identifiziert (z. B. eine Komponente einer Liste). Wenn er rechts vom Operator &lsquo $ &rsquo verwendet wird, muss er ein syntaktischer Name oder in Anführungszeichen sein. Andernfalls können Elementnamen beliebige Zeichenfolgen sein. (Wenn ein Objekt als Datenbank verwendet wird, wie bei einem Aufruf von eval() oder attach() , werden die Elementnamen zu Objektnamen.)
                5. Schließlich a Dateiname ist eine Zeichenfolge, die eine Datei im Betriebssystem zum Lesen, Schreiben usw. identifiziert. Es hat wirklich nicht viel mit Namen in der Sprache zu tun, aber es ist traditionell, diese Zeichenfolgen Datei &ldquonames&rdquo zu nennen.

                7.15 Sind GAMs in R implementiert?

                7.16 Warum wird die Ausgabe nicht gedruckt, wenn ich eine Datei source() verwende?

                Die meisten R-Befehle erzeugen keine Ausgabe. Der Befehl

                berechnet den Wert 2 und gibt ihm den Befehl zurück

                passt ein logistisches Regressionsmodell, berechnet einige Zusammenfassungsinformationen und gibt ein Objekt der Klasse "summary.glm" zurück (siehe Wie soll ich Zusammenfassungsmethoden schreiben?).

                Wenn Sie &lsquo 1+1 &rsquo oder &lsquo Zusammenfassung(glm(y

                x+z, family=binomial)) &rsquo an der Befehlszeile wird der zurückgegebene Wert automatisch ausgegeben (es sei denn, er ist unsichtbar() ), aber unter anderen Umständen, wie in einer source()-d-Datei oder innerhalb einer Funktion, wird er nicht gedruckt es sei denn, Sie drucken es ausdrücklich.

                stattdessen oder verwenden Sie source( file , echo=TRUE) .

                7.17 Warum verhält sich äußere() seltsam mit meiner Funktion?

                Wie die Hilfe für äußere() anzeigt, funktioniert es bei beliebigen Funktionen nicht wie die apply()-Familie. Es erfordert Funktionen, die vektorisiert sind, um elementweise auf Arrays zu arbeiten. Wie Sie beim Betrachten des Codes sehen können, erstellt äußere(x, y, FUN) zwei große Vektoren, die jede mögliche Kombination von Elementen von x und y enthalten, und übergibt diese dann auf einmal an FUN. Ihre Funktion kann wahrscheinlich nicht zwei große Vektoren als Parameter verarbeiten.

                Wenn Sie eine Funktion haben, die nicht mit zwei Vektoren, aber mit zwei Skalaren umgehen kann, können Sie immer noch outer() verwenden, aber Sie müssen Ihre Funktion zuerst umschließen, um vektorisiertes Verhalten zu simulieren. Angenommen, Ihre Funktion ist

                Wenn Sie die allgemeine Funktion definieren

                dann können Sie external() verwenden, indem Sie schreiben, z. B.:

                Skalare Funktionen können auch mit Vectorize() vektorisiert werden.

                7.18 Warum hängt die Ausgabe von anova() von der Reihenfolge der Faktoren im Modell ab?

                A+B+A:B , R gibt die Differenz der Quadratsummen zwischen den Modellen aus

                B+A+A:B , R würde Unterschiede zwischen . melden

                A+B+A:B . Im ersten Fall vergleicht die Quadratsumme für A

                A , im zweiten Fall vergleicht es

                B+A . In einem nicht orthogonalen Design (d. h. den meisten unausgeglichenen Designs) sind diese Vergleiche (konzeptionell und numerisch) unterschiedlich.

                Einige Pakete melden stattdessen die Quadratsummen basierend auf dem Vergleich des vollständigen Modells mit den Modellen, wobei jeder Faktor einzeln entfernt wurde (z. B. die berühmten &lsquoTyp-III-Quadratsummen&rsquo von SAS). Diese hängen nicht von der Reihenfolge der Faktoren im Modell ab. Die Frage, welche Menge von Quadratsummen das Richtige ist, provoziert von Zeit zu Zeit heilige Kriege auf niedriger Ebene gegen R-Hilfe.

                Es besteht kein Grund, sich über die speziellen Quadratsummen, die R berichtet, aufzuregen. Sie können Ihre Lieblingsquadratsummen ganz einfach berechnen. Zwei beliebige Modelle können mit anova( model1 , model2 ) verglichen werden, und drop1( model1 ) zeigt die Summen der Quadrate, die sich aus dem Weglassen einzelner Terme ergeben.

                7.19 Wie erzeuge ich PNG-Grafiken im Batch-Modus?

                Unter einem Unix-ähnlichen System sollte es keine Probleme geben, wenn Ihre Installation die Option type="cairo" für das png()-Gerät unterstützt, und die Standardeinstellungen sollten einfach funktionieren. Diese Option ist für Versionen von R vor 2.7.0 oder ohne Unterstützung für Kairo nicht verfügbar. Ab R 2.7.0 verwendet png() standardmäßig das Quartz-Gerät unter macOS, und das funktioniert auch im Batch-Modus.

                Frühere Versionen des png()-Geräts verwendeten den X11-Treiber, was im Batch-Modus oder für den Remote-Betrieb ein Problem darstellt. Wenn Sie über Ghostscript verfügen, können Sie bitmap() verwenden, das eine PostScript- oder PDF-Datei erzeugt und diese dann in jedes von Ghostscript unterstützte Bitmap-Format konvertiert. Bei einigen Installationen führt dies zu einer hässlichen Ausgabe, bei anderen ist es vollkommen zufriedenstellend. Viele Systeme kommen jetzt mit Xvfb von X.Org (eventuell als optionale Installation), das ist ein X11-Server, der keinen Bildschirm benötigt und es gibt die GDD -Paket von CRAN , das PNG-, JPEG- und GIF-Bitmaps ohne X11 erzeugt.

                7.20 Wie kann ich die Befehlszeilenbearbeitung zum Laufen bringen?

                7.21 Wie kann ich einen String in eine Variable umwandeln?

                Zumindest in den ersten beiden Fällen ist es oft einfacher, einfach eine Liste zu verwenden, und dann kann man sie einfach nach Namen indizieren

                ohne dass hier irgendwas herumgewirbelt wird.

                7.22 Warum funktionieren Gitter-/Trellis-Grafiken nicht?

                Der wahrscheinlichste Grund ist, dass Sie vergessen haben, R anzuweisen, das Diagramm anzuzeigen. Gitterfunktionen wie xyplot() erzeugen ein Graph-Objekt, zeigen es aber nicht an (dasselbe gilt für ggplot2 Grafiken und Trellis-Grafiken in S-PLUS). Die Methode print() für das Graph-Objekt erzeugt die eigentliche Anzeige. Wenn Sie diese Funktionen interaktiv in der Befehlszeile verwenden, wird das Ergebnis automatisch ausgegeben, aber in source() oder in Ihren eigenen Funktionen benötigen Sie eine explizite print()-Anweisung.

                7.23 Wie kann ich die Zeilen eines Datenrahmens sortieren?

                Um die Zeilen innerhalb eines Datenrahmens in Bezug auf die Werte in einer oder mehreren der Spalten zu sortieren, verwenden Sie einfach order() (zB DF[order(DF$a, DF[["b"]]), ] um die Datenrahmen DF auf Spalten mit den Namen a und b).

                7.24 Warum funktioniert die Suchmaschine help.start() nicht?

                Die browserbasierte Suchmaschine in help.start() verwendet ein Java-Applet. Damit dies ordnungsgemäß funktioniert, muss eine kompatible Java-Version auf Ihrem System installiert und mit Ihrem Browser verknüpft sein, und sowohl Java und JavaScript muss in Ihrem Browser aktiviert sein.

                Es gab eine Reihe von Kompatibilitätsproblemen mit Versionen von Java und von Browsern. Weitere Informationen finden Sie im Abschnitt &ldquoSuche in der HTML-Hilfe aktivieren&rdquo in R Installation and Administration . Dieses Handbuch ist in der R-Distribution enthalten, siehe Welche Dokumentation gibt es für R?, und seine HTML-Version ist auf der HTML-Suchseite verlinkt.

                7.25 Warum funktionierte mein .Rprofile nicht mehr, als ich R aktualisierte?

                Haben Sie die NEWS-Datei gelesen? Für Funktionen, die nicht im Base Paket müssen Sie den richtigen Paketnamensraum angeben, da der Code ausgeführt wird Vor die Pakete werden geladen. Z.B.,

                (graphics::ps.options(horizontal = FALSE) in R 1.9.x).

                7.26 Wo sind all die Methoden geblieben?

                Viele Funktionen, insbesondere S3-Methoden, sind jetzt in Namensräumen versteckt. Dies hat den Vorteil, dass sie nicht versehentlich mit Argumenten der falschen Klasse aufgerufen werden können, erschwert aber die Sichtbarkeit.

                Um den Code für eine S3-Methode (z. B. [.terms ) anzuzeigen, verwenden Sie

                Um den Code für eine nicht exportierte Funktion foo() im Namensraum des Pakets "bar" anzuzeigen, verwenden Sie bar. foo. Verwenden Sie diese Konstruktionen nicht, um nicht exportierte Funktionen in Ihrem eigenen Code aufzurufen. Sie sind wahrscheinlich aus einem bestimmten Grund nicht exportiert und können sich ohne Vorwarnung ändern.

                7.27 Wie kann ich gedrehte Achsenbeschriftungen erstellen?

                Um Achsenbeschriftungen (mit Basisgrafiken) zu drehen, müssen Sie text() anstelle von mtext() verwenden, da letzteres par("srt") nicht unterstützt.

                Beim Plotten der X-Achsen-Beschriftungen verwenden wir srt = 45 für den Textdrehwinkel, adj = 1, um das rechte Ende des Textes an den Teilstrichen zu platzieren, und xpd = TRUE, um Text außerhalb des Plotbereichs zuzulassen. Sie können den Wert des 0,25-Offsets nach Bedarf anpassen, um die Achsenbeschriftungen relativ zur x-Achse nach oben oder unten zu verschieben. Siehe ?par für weitere Informationen.

                Siehe auch Abbildung 1 und den zugehörigen Code in Paul Murrell (2003), &ldquoIntegrating grid Graphics Output with Base Graphics Output&rdquo, R Nachrichten, 3/2, 7&ndash12.

                7.28 Warum ist read.table() so ineffizient?

                Standardmäßig muss read.table() alles als Zeichendaten einlesen und dann versuchen herauszufinden, welche Variablen in Zahlen oder Faktoren umgewandelt werden sollen. Bei einem großen Datensatz nimmt dies viel Zeit und Speicher in Anspruch. Die Performance kann wesentlich verbessert werden, indem das Argument colClasses verwendet wird, um die anzunehmenden Klassen für die Spalten der Tabelle anzugeben.

                7.29 Was ist der Unterschied zwischen Paket und Bibliothek?

                EIN Paket ist eine standardisierte Materialsammlung, die R erweitert, z.B. Bereitstellung von Code, Daten oder Dokumentation. EIN Bibliothek ist ein Ort (Verzeichnis), an dem R Pakete finden kann, die es verwenden kann (d. h. welche Eingerichtet). R wird über Aufrufe der Funktionsbibliothek angewiesen, ein Paket zu verwenden (um es zu &ldquoladen&rdquo und zum Suchpfad hinzuzufügen). D.h., library() wird verwendet, um ein Paket aus Bibliotheken zu laden, die Pakete enthalten.

                Weitere Informationen finden Sie unter R-Add-On-Pakete. Siehe auch Uwe Ligges (2003), &ldquoR Help Desk: Package Management&rdquo, R Nachrichten, 3/3, 37&ndash39.

                7.30 Ich habe ein Paket installiert, aber die Funktionen sind nicht da

                Um eigentlich benutzen das paket, es muss sein geladen mit Bibliothek() .

                7.31 Warum denkt &rsquot R, dass diese Zahlen gleich sind?

                Die einzigen Zahlen, die im numerischen Typ R&rsquo exakt dargestellt werden können, sind ganze Zahlen und Brüche, deren Nenner eine Potenz von 2 ist. Alle anderen Zahlen werden intern auf (typischerweise) 53 binäre Stellen gerundet. Infolgedessen sind zwei Gleitkommazahlen nicht zuverlässig gleich, es sei denn, sie wurden mit demselben Algorithmus berechnet, und selbst dann nicht immer. Beispielsweise

                Die Funktion all.equal() vergleicht zwei Objekte mit einer numerischen Toleranz von .Machine$double.eps ^ 0.5 . Wenn Sie eine viel höhere Genauigkeit wünschen, müssen Sie die Fehlerausbreitung sorgfältig prüfen.

                Eine Diskussion mit vielen leicht nachvollziehbaren Beispielen findet sich in Anhang G &ldquoComputational Precision and Floating Point Arithmetic&rdquo, Seiten 753&ndash771 von Statistische Analyse und Datenanzeige: Ein Aufbaukurs mit Beispielen in R, Richard M. Heiberger und Burt Holland (Springer 2015, 2. Auflage). Dieser Anhang kann kostenlos von http://link.springer.com/content/pdf/bbm%3A978-1-4939-2122-5%2F1.pdf heruntergeladen werden.

                Weitere Informationen finden Sie z.B. David Goldberg (1991), &ldquoWas jeder Informatiker über Gleitkomma-Arithmetik wissen sollte&rdquo, ACM-Computing-Umfragen, 23/1, 5&ndash48, auch verfügbar über http://www.validlab.com/goldberg/paper.pdf.

                Hier ist ein weiteres Beispiel, diesmal mit Addition:

                7.32 Wie kann ich Fehler in einer langen Simulation erfassen oder ignorieren?

                Verwenden Sie try() , das statt eines Fehlers ein Objekt der Klasse "try-error" zurückgibt, oder vorzugsweise tryCatch() , wo der Rückgabewert flexibler konfiguriert werden kann. Beispielsweise

                würde die Koeffizienten zurückgeben, wenn der Aufruf von lm() erfolgreich war, und würde c(NaN, NaN, NaN, NaN) zurückgeben, wenn er fehlgeschlagen ist (in diesem Beispiel sollen es vermutlich 4 Koeffizienten geben).

                7.33 Warum sind Potenzen negativer Zahlen falsch?

                Sie sehen wahrscheinlich so etwas wie

                und missverstehen die Vorrangregeln für Ausdrücke in R. Write

                Die Vorrangregeln sind in ?Syntax dokumentiert, und um zu sehen, wie R einen Ausdruck interpretiert, können Sie sich den Parse-Baum ansehen

                7.34 Wie kann ich das Ergebnis jeder Iteration in einer Schleife in einer separaten Datei speichern?

                Eine Möglichkeit besteht darin, paste() (oder sprintf() ) zu verwenden, um einen Stammdateinamen und die Iterationsnummer zu verketten, während file.path() den Pfad konstruiert. Um beispielsweise Ergebnisse in den Dateien result1.rda , &hellip, result100.rda im Unterverzeichnis Results des aktuellen Arbeitsverzeichnisses zu speichern, kann man

                7.35 Warum sind p-Werte werden bei Verwendung von lmer() nicht angezeigt?

                Doug Bates hat freundlicherweise in einem Beitrag zur r-help-Liste eine ausführliche Antwort bereitgestellt, die unter https://stat.ethz.ch/pipermail/r-help/2006-May/094765.html eingesehen werden kann.

                7.36 Warum treten beim Anzeigen eines in einer PS- oder PDF-Datei gespeicherten Plots unerwünschte Ränder, Linien oder gitterartige Artefakte auf?

                Dies kann vorkommen, wenn Funktionen wie polygon() , fill.contour() , image() oder andere Funktionen verwendet werden, die diese intern aufrufen können. Im Fall von polygon() können Sie ungewollte Grenzen zwischen den Polygonen beobachten, selbst wenn Sie das Grenzargument auf NA oder "transparent" setzen.

                Die Ursache des Problems ist der PS/PDF-Viewer, wenn der Plot geglättet ist. Die Details für die Lösung unterscheiden sich je nach verwendetem Viewer und Betriebssystem und können sich im Laufe der Zeit ändern. Berücksichtigen Sie für einige gängige Betrachter Folgendes:

                Acrobat Reader (plattformübergreifend)

                In den Einstellungen gibt es Optionen zum Aktivieren/Deaktivieren der Textglättung, Bildglättung und Strichgrafik-Glättung. Deaktivieren Sie die Strichgrafik-Glättung.

                In den Einstellungen gibt es eine Option zum Aktivieren/Deaktivieren des Anti-Aliasing von Text und Strichzeichnungen. Deaktivieren Sie diese Option.

                Es gibt Einstellungen für Text Alpha und Grafik Alpha. Ändern Sie Graphics Alpha von 4 Bit auf 1 Bit, um das grafische Anti-Aliasing zu deaktivieren.

                Es gibt eine Option zum Aktivieren/Deaktivieren von Anti-Aliasing. Deaktivieren Sie diese Option.

                In diesem Viewer gibt es keine Option zum Deaktivieren von Anti-Aliasing.

                Es gibt keine Option in der GUI zum Aktivieren/Deaktivieren von Anti-Aliasing. Verwenden Sie in einer Konsolenbefehlszeile:

                Starten Sie dann Okular neu. Ändern Sie das letzte Wort in &lsquo Aktiviert &rsquo, um die ursprüngliche Einstellung wiederherzustellen.

                7.37 Warum verhält sich Backslash innerhalb von Strings seltsam?

                Diese Frage wird am häufigsten in Bezug auf Dateinamen gestellt (siehe Wie funktionieren Dateinamen in Windows?), aber es kommt auch vor, dass sich Leute darüber beschweren, dass sie anscheinend kein einzelnes &lsquo &rsquo-Zeichen in eine Textzeichenfolge einfügen können, es sei denn, es ist zufällig gefolgt von bestimmten anderen Zeichen.

                Um dies zu verstehen, muss man zwischen Zeichenketten und Vertretungen von Zeichenketten. Meistens ist die Darstellung in R nur die Zeichenfolge mit einem einfachen oder doppelten Anführungszeichen an beiden Enden, aber es gibt Zeichenfolgen, die nicht auf diese Weise dargestellt werden können, z. B. Zeichenfolgen, die selbst das Anführungszeichen enthalten. So

                Das Escape-Sequenzen &lsquo " &rsquo und &lsquo &rsquo stehen für ein doppeltes Anführungszeichen bzw. das Zeilenumbruchzeichen. Wenn Sie Textstrings drucken, print() verwenden oder den Namen an der Eingabeaufforderung eingeben, werden auch die Escape-Sequenzen verwendet, aber die Funktion cat() zeigt den String unverändert an. Beachten Sie, dass &lsquo " " &rsquo eine einstellige Zeichenfolge ist, nicht zwei, der umgekehrte Schrägstrich ist nicht wirklich in der Zeichenfolge enthalten, sondern wird nur in der gedruckten Darstellung generiert.

                Wie fügt man also einen Backslash in einen String ein? Dazu müssen Sie das Escape-Zeichen mit Escapezeichen versehen. D.h. Sie müssen den Backslash verdoppeln. wie in

                Einige Funktionen, insbesondere diejenigen, die einen Vergleich mit regulären Ausdrücken beinhalten, verwenden selbst Metazeichen, die möglicherweise durch den Backslash-Mechanismus maskiert werden müssen. In diesen Fällen benötigen Sie möglicherweise eine vervierfachen Backslash, um ein einzelnes Literal darzustellen.

                In Versionen von R bis 2.4.1 wurde eine unbekannte Escape-Sequenz wie &lsquo p &rsquo stillschweigend als einfach &lsquo p &rsquo interpretiert. Aktuelle Versionen von R geben eine Warnung aus.

                7.38 Wie kann ich meinem Plot Fehlerbalken oder Konfidenzbänder hinzufügen?

                Einige Funktionen zeigen eine bestimmte Art von Diagramm mit Fehlerbalken an, wie die Funktion bar.err() in der in agricolae Paket, die Funktion plotCI() in der gplots Paket, die Funktionen plotCI() und brkdn.plot() in der Plotrix -Paket und die Funktionen error.bars() , error.crosses() und error.bars.by() in der psychisch Paket. Innerhalb dieser Arten von Funktionen akzeptieren einige die Streuungsmaße (z. B. plotCI ), einige berechnen die Streuungsmaße aus den Rohwerten ( bar.err , brkdn.plot ) und manche tun beides ( error.bars ). Wieder andere Funktionen zeigen nur Fehlerbalken an, wie die Dispersionsfunktion im Plotrix Paket. Die meisten der oben genannten Funktionen verwenden die Funktion arrows() in der Basis Grafik Paket, um die Fehlerbalken zu zeichnen.

                Die oben genannten Funktionen verwenden alle das Basisgrafiksystem. Die Raster- und Gittergrafiksysteme verfügen auch über spezielle Funktionen zur Anzeige von Fehlerbalken, z. B. die Funktion grid.arrow() im Gitter -Paket und die Funktionen geom_errorbar() , geom_errorbarh() , geom_pointrange() , geom_linerange() , geom_crossbar() und geom_ribbon() in der ggplot2 Paket. Im Gittersystem können Fehlerbalken mit Dotplot() oder xYplot() im Hmisc package und segplot() im GitterExtra Paket.

                7.39 Wie erstelle ich einen Plot mit zwei y-Achsen?

                Das Erstellen eines Diagramms mit zwei y-Achsen, dh mit zwei Arten von Daten, die auf die gleiche vertikale Größe skaliert sind und auf der linken und rechten Seite des Diagramms separate vertikale Achsen zeigen, die die ursprünglichen Skalen der Daten widerspiegeln, ist in . möglich R, wird aber nicht empfohlen. Der grundlegende Ansatz für die Konstruktion solcher Graphen besteht darin, par(new=TRUE) (siehe ?par ) Funktionen twoord.plot() (in der Plotrix Paket) und doubleYScale() (im GitterExtra Paket) automatisieren den Prozess etwas.

                7.40 Wie greife ich auf den Quellcode einer Funktion zu?

                In den meisten Fällen wird durch Eingabe des Namens der Funktion deren Quellcode ausgegeben. Code wird jedoch manchmal in einem Namespace versteckt oder kompiliert. Eine vollständige Übersicht über den Zugriff auf Quellcode finden Sie in Uwe Ligges (2006), &ldquoHelp Desk: Accessing the sources&rdquo, R Nachrichten, 6/4, 43&ndash45 (https://CRAN.R-project.org/doc/Rnews/Rnews_2006-4.pdf).

                7.41 Warum meldet Summary() seltsame Ergebnisse für die R^2-Schätzung, wenn ich ein lineares Modell ohne Achsenabschnitt passe?

                Wie in ?summary.lm beschrieben, wenn der Achsenabschnitt null ist (z. B. von y

                x + 0 ), Summary.lm() verwendet die Formel R^2 = 1 - Sum(R[i]^2) / Sum((y[i])^2) die sich vom üblichen R^2 = . unterscheidet 1 - Summe(R[i]^2) / Summe((y[i] - Mittelwert(y))^2). Dafür gibt es mehrere Gründe:

                • Ansonsten der R^2 könnte negativ sein (weil das Modell mit Nullabschnitt passen kann schlechter als das Modell mit konstantem Mittelwert, mit dem es implizit verglichen wird).
                • Wenn Sie im Modell mit einer Linie durch den Ursprung die Steigung auf Null setzen, erhalten Sie angepasste Werte y*=0
                • Das Modell mit konstantem Mittelwert ungleich Null ist nicht mit einer Linie durch den Ursprung im Modell verschachtelt.

                All dies läuft darauf hinaus, zu sagen, dass wenn Sie es wissen a priori Das E[Y]=0 wann x=0 dann das &lsquonull&rsquo-Modell, das Sie mit der angepassten Linie vergleichen sollten, das Modell, bei dem x Erklärt die Varianz nicht, ist das Modell, bei dem E[Y]=0 überall. (Wenn Sie das nicht a priori wissen E[Y]=0 wann x=0, dann sollten Sie wahrscheinlich eine Linie durch den Ursprung einfügen.)

                7.42 Warum gibt R anscheinend keinen Speicher frei?

                Diese Frage wird oft in verschiedenen Variationen gestellt, ähnlich wie &ldquoIch habe Objekte in R entfernt und gc() ausgeführt und dennoch zeigt ps/top immer noch an, dass der R-Prozess viel Speicher beansprucht&rdquo, oft auf Linux-Rechnern.

                Dies ist ein Artefakt der Art und Weise, wie das Betriebssystem (OS) Speicher zuweist. Im Allgemeinen ist es üblich, dass das Betriebssystem nicht in der Lage ist, den gesamten ungenutzten Speicher freizugeben. In extremen Fällen ist es möglich, dass das Betriebssystem, selbst wenn R fast seinen gesamten Speicher freigibt, aufgrund seines Designs nichts davon freigeben kann und daher Tools wie ps oder top eine erhebliche Menge an residentem RAM melden, die vom R-Prozess verwendet wird, obwohl even R hat all diese Erinnerung freigegeben. Im Allgemeinen tun solche Tools nicht berichten Sie über die tatsächliche Speichernutzung des Prozesses, sondern darüber, was das Betriebssystem für diesen Prozess reserviert.

                Die kurze Antwort ist, dass dies eine Einschränkung der Speicherzuweisung im Betriebssystem ist und R nichts dagegen tun kann. Dieser Speicherplatz wird einfach vom Betriebssystem in der Hoffnung gehalten, dass R später danach fragt. Der folgende Absatz gibt eine ausführlichere Antwort mit technischen Details dazu, wie dies geschieht.

                Die meisten Systeme verwenden zwei verschiedene Möglichkeiten, um Speicher zuzuweisen. Für die Zuweisung großer Chunks verwenden sie mmap, um den Speicher dem Prozessadressraum zuzuordnen. Solche Chunks können sofort freigegeben werden, wenn sie vollständig frei sind, da sie sich überall im virtuellen Speicher befinden können. Dies ist jedoch ein relativ kostspieliger Vorgang, und viele Betriebssysteme haben eine Begrenzung der Anzahl solcher zugewiesener Blöcke, sodass dies nur zum Zuweisen großer Speicherbereiche verwendet wird. Bei kleineren Zuordnungen kann das System den Datenabschnitt des Prozesses erweitern (historisch über den Systemaufruf brk), aber dieser ganze Bereich ist immer zusammenhängend. Das Betriebssystem kann nur das Ende dieses Bereichs verschieben, es kann keine &ldquoholes&rdquo erstellen. Da dieser Vorgang relativ kostengünstig ist, wird er für die Zuweisung kleiner Speicherteile verwendet.Der Nebeneffekt ist jedoch, dass das Betriebssystem selbst dann, wenn nur ein Byte am Ende des Datensegments verwendet wird, keinen Speicher freigeben kann, da es die Adresse dieses Bytes nicht ändern kann. Dies ist tatsächlich häufiger als es den Anschein hat, da das Zuweisen vieler Zwischenobjekte, das Zuweisen eines Ergebnisobjekts und das Entfernen aller Zwischenobjekte eine sehr gängige Praxis ist. Da das Ergebnis am Ende zugewiesen wird, wird verhindert, dass das Betriebssystem den von den Zwischenobjekten verwendeten Speicher freigibt. In der Praxis stellt dies nicht unbedingt ein Problem dar, da moderne Betriebssysteme ungenutzte Teile des virtuellen Speichers auslagern können, sodass die für andere Anwendungen verfügbare Menge an realem Speicher nicht unbedingt reduziert wird. Typischerweise sind kleine Objekte wie Strings oder Paarlisten von diesem Verhalten betroffen, während große Objekte wie lange Vektoren mit mmap zugewiesen und somit nicht betroffen sind. Unter Linux (und möglicherweise anderen Unix-ähnlichen Systemen) ist es möglich, den Allocator über den Mallinfo-Systemaufruf (siehe auch das Mallinfo-Paket) nach dem Layout der Allokationen abzufragen, einschließlich des tatsächlich verwendeten Speichers sowie des nicht verwendeten Speichers, der nicht veröffentlicht werden.


                Schau das Video: Multiple Polygons into Single Polygon Dissolve tool Correct way!!