MySQL Große Datenmengen reibungslos speichern für Gameserver

Elmo123

Mitglied
Hallo!

Nun ich habe das Problem das wenn ich Daten in einen MySql-Datenbank eintrage das sich das durch Aufhänger im Spiel bemerkbar macht. Ich habe jetzt schon viele Speichermethoden ausprobiert sowie direktes speichern und zeit gesteuertes speichern (alle 5 min) immer hängt sich das Spiel für ein paar Sekunden auf bzw der Gameserver. Als nächstes wolle ich es mal mit einer warteschlange (Queue) ausprobieren also alle Queries nacheinander ausführen.

Aber bevor ich das ausprobiere wollte ich mal wissen ob ihr ein paar Tipps für mich habt wie ich schnell speichern kann.

Noch ein paar Infos:

Laut PhpMyAdmin statistiken sind seit start (ein zeitraum von 15 stunden) 200.000 verbindungen eingegangen.

Und an der hardware liegt es sicher auch nicht ( 32gb ram, i7).

MfG
 

Elmo123

Mitglied
AutoSave.java :
Java:
public class AutoSave extends Thread {
	
	private boolean run = true;
	private long wait = 300000L;
	
	
	public void setRun(boolean run) {
		this.run = run;
	}
	
	public void setDelay(long wait) {
		this.wait = wait;
	}
	
	 public void run () {
		 while (this.run) {
			MySql.savePlayers();
			System.out.print("[Server] AutoSave.");
			try {
				Thread.sleep(wait);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		 }
	 } 
	 
}

MySql.java:
Java:
public class MySql {

	public static Connection connect;
	private static List<Player> onlinePlayers = new ArrayList<Player>();

	public static boolean connect(String MySQLhost, String MySQLdatabase, String MySQLuser, String MySQLpasswd, int MySQLport) {

		String connection = "jdbc:mysql://" + MySQLhost + ":" + MySQLport + "/" + MySQLdatabase;
		try {
			Class.forName("com.mysql.jdbc.Driver").newInstance();
			connect = DriverManager.getConnection(connection, MySQLuser, MySQLpasswd);
			System.out.print("[Server] MySQL connection is ok.");
			return true;
		} catch (Exception ex) {
			System.out.print("[Server] There was an Error (Connect) : " + ex);
			return false;
		}

	}
	
	public static void savePlayers() {
		try {
			Statement statement = connect.createStatement();
			statement.execute("LOCK TABLES player WRITE");
			for(Player player : onlinePlayers) {
				statement.executeUpdate("UPDATE player SET kills='" 
										+ player.getKills() 
										+ "', deaths='" 
										+ player.getDeaths() 
										+ "' WHERE name='"
										+ player.getName() 
										+"';");
			}
			statement.execute("UNLOCK TABLES");
			statement.close();
		}catch (SQLException ex) {
			System.err.println("[Server] There was an Error (savePlayers) : " + ex);
		}
	}

	public static boolean close() {
		try {
			connect.close();
			return true;
		} catch (Exception ex) {
			return false;
		}
	}

}

connect(..) wird beim starten des servers aufgerufne und close() beim stopen des servers.
asußerem habe ich den code in MySql.java etwas zusammengefasst und verkürzt das es sinn ergibt aber so siehts ca aus.

Mfg
 

TheDarkRose

Gesperrter Benutzer
Statt selbst zu locken, solltest du das lieber der Engine (InnoDB) überlassen und Transaktionen verwenden.

Um wieviel Player handelt es sich denn? Ist player.name indiziert?

Gesendet von meinem Nexus 4 mit Tapatalk 2
 

Elmo123

Mitglied
Also meinst du statt LOCK TABLES eher START TRANSACTION; und COMMIT; verwenden?
Und die anzahl der Spieler variiert immer zwischen 100 und 300.
und ja.
 

Ähnliche Java Themen

Neue Themen


Oben