Update Strategie

daemon777

Lt. Commander
Registriert
Dez. 2003
Beiträge
1.371
Hallo Leute,

zur Zeit mache ich mir über ein Thema Gedanken, bei dem ich irgendwie noch nicht ganz zu einem Ergebnis gekommen bin. Hierbei geht es darum, wie man ein Programm so entwerfen kann, dass es sich möglichst gut warten, updaten und upgraden lässt bzw. wie man so einen Patch dann am Besten entwerfen kann. Dabei gliedert sich das Problem grundsätzlich in zwei Teilprobleme:

1. Die Gliederung des Programms (Viel in Bibliotheken auslagern?)
2. Das Patchen an sich

1. Hier stellt sich mir derzeit die Frage, ob es Sinn macht Teile des Programmes in dlls auszulagern, um diese dann im Falle eines Updates einfacher austauschen zu können.
Generell fände ich es aber schöner, wenn das Programm auf einem Server nachschlägt, welche Version aktuell ist und dann nur die veränderten Informationen herunterladen muss.

2. Deshalb wäre es schön, wenn man eine Datei erstellen würde, die nur die Unterschiede zur alten Version enthält, um zu verhindern, dass die komplette ausführbare Datei oder eine komplette Bibliothek geladen werden muss. Aber irgendwie erscheint es mir ziemlich aufwändig solch eine Datei zu berechnen.

Gibt es hierfür vielleicht Artikel, die man nachlesen kann? Bisher habe ich da leider nichts brauchbares gefunden. Irgendwie muss es aber bei so etwas auch Standardvorgehen geben. Schließlich gibt es ja Patches und Spiele wie Minecraft schaffen es ja auch sich selbstständig upzudaten, ohne dass der Benutzer hier manuell Patches herunterladen müsste.

Bisher ist das für mich nur ein rein theoretisches Problem, aber es ist eines, das mich nicht wieder loslässt. Das ist also mal einer der Threads, wo eine rege Diskussion gewünscht ist :D

viele Grüße
daemon
 
die patches bei spielen sind ausführbare dateien die informationen bzw dateien enthalten die geupdatet werden müssen. dies macht bei sehr großen programmen sinn. bei 10MB programmen lohnt glaub ich der Aufwand nicht.

ein weiteres tool ist diff und patch...kannste ja mal googlen...wird häufig auf sourcecode level verwendet.
 
Problem beim "auslagern" ist, dass man Inkompatiblitäten vermeiden muss - verschiedene Versionen der DLLs könnten ja uU nicht mit deinem eigentlichen Programm in einer bestimmten Verison zusammenarbeiten. Sprich: ein Programm muss in der Lage sein, inkompatible Konfigurationen zu "erkennen". Im einfachsten Fall einfach durch den Check, ob eine DLL exakt die richtige Revision hat - aber wenn das zu einfach ausgeführt wird, dann hast du eine nie mehr enden wollende Reihe aus Inkompatiblitäten wenn ein Nutzer manuell eine Datei austauscht...

Was Minecraft als Beispiel angeht: Da hast du einen Launcher, der deine Version mit der ausm Internet vergleicht. Wenn der eine neue Version findet, tauscht er die minecraft.jar aus, und lädt zusätzlich noch benötigte externe Ressourcen nach. Wirklich "gepatcht" wird da eigentlich nicht, sondern eben das ganze "Programm" ausgetauscht.

mfg
 
Grundsätzlich mal die Frage, mit welchem SDK oder welcher Engine entwickelst du denn? Das klingt für mich erst mal danach, dass du für Windows entwickelst/entwickeln möchtest?

Ein Negativ-Beispiel fürs Allgemeinwissen ist meiner Meinung nach Battlefield3/4. Schon ein simpler (angeblicher) Bug-Fix Patch kann da 3-4 GB groß sein. Ich vermute, dass DICE die Änderungen in ein oder zwei größeren Dateien gespeichert hat, die dann natürlich komplett neu geladen werden müssen. Freut mich immer besonders bei meiner Holz-Leitung ;)

Dieser Fall ist natürlich nicht optimal - kann aber verschiedene Gründe haben wie zB Cheat/Mod Schutz etc.

Bei mobilen Apps/Games muss häufig die komplette app neu geladen werden. Wenn man während Patches *nur* bestimmte Variablen ändern muss/möchte, dann lohnt es sich da allerdings diese regelmäßig von einem externen Server neu zu laden und den Nutzer per benachrichtigung darauf aufmerksam zu machen. Man spart dabei wichtige Zeit ;)

Am PC/Mac kann man je nach Engine wirklich nur die Dateien austauschen, die eine Änderung benötigen. Eine Auslagerung von bestimmten Dingen wie Parametern, Variablen etc macht da denke ich Sinn. Kommt aber alles auf deine Anwendung an ;)
 
@honky-tonk
Danke für deine Antwort. Dass sich der Aufwand für kleinere Programme nicht lohnt ist mir schon bewusst, aber mir geht es ja auch mehr um die theoretische Betrachtung. Abgesehen davon ist es auch bei einem 10 MB Programm schon ärgerlich, wenn jemand die ganzen 10MB laden muss, nur weil sich vielleicht ein paar Byte geändert haben.
Das Patch-Programm ist ja ziemlich simpel, wenn man erstmal die Änderungen in einer Datei hat. Was das diff-Programm angeht, so geht das schonmal in die richtige Richtung. Schonmal gut da ein Beispiel zu sehen. Allerdings arbeitet das ja leider Zeilenweise. Dass man hier Quellcode-basiert gut Patchen kann ist ein interessanter Gedanke, der mir bisher noch nicht gekommen ist. Bei OpenSource-Projekten sicher eine interessante Alternative.

@ HominiLupus
Das liest sich auf den ersten Blick genau wie das, was ich suche. Sehr schön. Danke :)
Dass so ein Delta-Update bei Binärdaten nicht ganz einfach ist habe ich auch schon bemerkt. Deshalb habe ich ja den Thread hier erstellt. Ganz trivial ist das Thema nämlich wirklich nicht.
Deine Links geben mir jetzt erstmal ne Menge zu lesen. Vielleicht finde ich dabei ja schon einen Algorithmus, der halbewegs effizient das tut, was ich suche.
Ergänzung ()

@KainerM
Stimm das mit den Inkompatibilitäten könnte dann tatsächlich schnell zum Problem werden. Gerade bei offenen Projekten, wo sich eine Community mit Mods oder Ähnlichem bildet kann einem das wohl recht schnell um die Ohren fliegen.
Da müsste man sich etwas clevereres (was ein Wort o.O) einfallen lassen, als ein einfacher Revisionscheck.
Aber wenn man so etwas wie Mods zulassen will, dann hat man damit wohl sowieso immer gewisse Schwierigkeiten.

Dass minecraft tatsächlich die komplette jar austauscht war mir nicht bewusst. Gerade bei einem so großen Spiel, aber dennoch zu Anfang low-budget, hätte ich vermutet, dass hier an Bandbreite gespart wird, wo nur irgend möglich. So kann man sich täuschen.


@CineTek
Das mit BF ist ja ein lustiges Beispiel dafür, wie ich es gerade nicht machen möchte :)
Dass man Cheats/Cracks etc wohl auch einfacher für eine neue Version patchen kann, wenn man die Änderungen zwischen zwei unterschiedlichen Versionen auslesen kann, ist wohl so. Das ist also dann noch ein weiteres Problem.

Bisher sind meine Überlegungen tatsächlich rein theoretischer Natur. Ich selbst arbeite zwar hauptsächlich unter Windows, allerdings steige ich da jetzt auf Qt um, da ich ungern an eine Platform gebunden bin. Mir geht es eigentlich darum für mich selbst in der Zukunft ein generelles Vorgehen zu überlegen, falls ich Software entwerfen will. Im Moment bin ich aber einfach nur neugierig, wie man so etwas möglichst optimal handhaben kann.

Dass man nur die Dateien patcht, die auch verändert wurden, ist ja nicht das große Problem. Dass man sich von vorne herein Gedanken darüber macht, welche Daten eventuell geändert werden müssen und diese entweder direkt im Programm von Server lädt oder diese in eine extra Datei verfrachtet, ist schonmal ein sehr guter Gedanke, der mir schon sehr gut gefällt. So könnte man sich wohl teilweise aufwendige Patches sparen.
 
CineTek schrieb:
Ein Negativ-Beispiel fürs Allgemeinwissen ist meiner Meinung nach Battlefield3/4. Schon ein simpler (angeblicher) Bug-Fix Patch kann da 3-4 GB groß sein. Ich vermute, dass DICE die Änderungen in ein oder zwei größeren Dateien gespeichert hat, die dann natürlich komplett neu geladen werden müssen. Freut mich immer besonders bei meiner Holz-Leitung ;)
Ähm, nö. Stimmt nicht. Die letzten Tage kam z.B. wieder ein Bugfix für BF4, der nur 250MB groß war.
Viele Patches sind 3-4GB groß, weil diese Patches Bugs in Karten beseitigen, z.B. Exploit-Spots oder Stellen, wo man sinnlos hängen bleiben kann. Hierfür muss die ganze Karte neu geladen werden, was eben pro Karte 1-2GB sind. Über die Dateiverwaltung kann man gut verfolgen, was sich wie ändert.

Allgemeine Patchstrategie: Teile und herrsche.
Leg eine Hash-Liste aller Dateien an, die zu deinem Programm gehören. Verwende viele kleine Dateien, die du dann in Paketen bündelst, ohne zu komprimieren. Tausche beim Update dann nur die Dateien aus, deren Hash nicht passt. Schau dir z.B. mal an, wie Blizzard das lösen, ist ziemlich genial mit ihren MPQs.
 
Das mit den MPQs scheint echt ganz schick zu sein. Bisher habe ich um das Thema Hashing immer einen großen Bogen gemacht, aber irgendwann ist der punkt gekommen, wo man sich klar machen muss, dass es wohl doch Sinn machen muss, wenn so viele Leute darauf schwören. Spätestens ab einer gewissen Komplexität der Daten ist es wohl eh unerlässlich.

Ich bedanke mich für eure Antworten. Dank dem Thread habe ich jetzt eine etwas genauere Vorstellung, wie so eine Strategie aussehen sollte. Das Thema Delta-Updates werde ich dann erstmal verschieben und dann weiterverfolgen, wenn es denn wieder aktueller wird. Aber ganz loslassen wird mich das Thema wohl trotzdem nicht :D
 
Zurück
Oben