#Data Synchronization across servers with Redis
1 messages · Page 1 of 1 (latest)
yeah btw aglerr im thinking of a solution
hmm
Can I keep cache on the redis?
Like load the clan on server startup, and if the clan is not on redis cache, load it from the MySQL.
Database -> redis
you shouldnt really use redis as database...
I couldn't think of any different solutions right now
Usually,
get data:
if data is not in local cache -> check redis cache -> if not in redis cache -> check persistent database -> if in p-db but not in redis-cache put in redis-cache
tho it requires you to be disciplined
the hard problem is to avoid invalid data
And somehow we need to save the data to mysql too before it expires.
I believe you can attach an expiration-listener
if not
whenever you update the cache, update the mysql database also
The bedwars clan data will be changed very often I imagine, isn't that will be expensive?
I mean do it concurrently
okay aglerr
I think you could do it like that and
in addition, whenever a foreign server sends an update, grab the updated data directly from the rediscache
Wait, so have a global hashmap on redis and load/update data from there?
yes but also a local one
And use this system right?
if data is not in local cache -> check redis cache -> if not in redis cache -> check persistent database -> if in p-db but not in redis-cache put in redis-cache
And cache it on the local when server startup?
I think so
What about try to load clans on PlayerJoin, so when player join get the clan uuid and if the clan is not on local cache/redis cache, load it directly from mysql
First and foremost, use APPLE event but yeah
I don't think I want to loop through all clans, and also it has multiple tables which is kinda confusing.
What is APPLE event?
AsyncPlayerPreLoginEvent
Oh okay, lmao.
let me write some cases for you
actually
what data are you saving?
or well
managing?
just clan data?
or player data also?
player data for the rank in the clan, and what clan they are in
Don't you have a data-transfer-object?
right
also, i use player name to identify the player, don't be mad tho 😅
👀
all of the uuid is clan's uuid
Okay
When a user joins a server, load the data
┕-if not in redis cache
┕-queue persistent database
┕-put result in redis cache
┕-put result in local hashmap
┕-get result from local hashmap```
I need to load the clan's data too right?
yeah not done xD
For aglerr, this is a proposal of data modelling and managing When the player joins Load data from redis cache Put in local hashmap If data is not redis cache Load data from mysql Put in redis cache Put in local hashmap When player leaves Put the player data in redis cache Put the player data in...
havent written about clan data
Thanks for the details, take a look at this https://github.com/aglerr/clan/blob/master/src/main/java/co/vargoi/clan/database/redis/ClanCache.java
Is it like that?
Gonna write some concerning clans
Also I make it method return boolean, so we know If the loading fails or not
I already do that
Yeah no need for that bool
@EventHandler
public void onAsyncPreLogin(AsyncPlayerPreLoginEvent event){
if(!clanCache.loadPlayerSync(event.getName())){
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
event.setKickMessage("Failed to load your data");
}
}
``` I want to do something like this, or just make the method void?
That’s probably fine
okay great!
Anyways
I’m just doubtful whether it’s smart to keep all clans loaded in the local hashmap as well in the redis cache
I don't know what are the limitations of the Redis Cache.
These are the updated code:
ClanCache.java - https://github.com/aglerr/clan/blob/master/src/main/java/co/vargoi/clan/database/redis/ClanCache.java
PlayerListeners.java - https://github.com/aglerr/clan/blob/master/src/main/java/co/vargoi/clan/listeners/PlayerListeners.java
@supple parrot If you save user's data when they leaves, do we need to use pub/sub for that? I mean you have saved it on redis cache when player leaves.
Yes it’s smart to save it there
and use pub sub
Such that other servers can pickup any changes
I don't know what's the correct way but apparently, you can't use Jedis#hgetall on subscribe listener. https://paste.md-5.net/qucuzonazi.md
Do I need to send a message like aglerr;clanuuid;rank and then split it or something.
@supple parrot
send code
i'd use gson
Never used gson but I'll read the docs first.
Can you just GSON#toJson(clanPlayerObject) and vice-versa?
Should I create a single and keep the reference of Gson object, or just use new Gson everytime I needed it?
On publish
try(Jedis jedis = redisHandler.getJedisPool().getResource()){
jedis.auth(redisHandler.getPassword());
jedis.publish(RedisHandler.CHANNEL_CLAN_PLAYER, gson.toJson(clanPlayer));
}
On subscribe
ClanPlayer clanPlayer = gson.fromJson(message, ClanPlayer.class);
clanPlayerMap.put(message, clanPlayer);
Create a reference for sure
yuh fine
I have a field for the gson
private final Gson gson = new Gson();
That's pretty useful ngl lmao
You can easily convert object to string in json format and convert json format to the object itself
I'm so happy ajdnjawndawndsadwk
But my friend says, it's better to store the data one by one to Redis instead store it as a Json @wary mango, what do you think?
Who’s your friend?
Anyways that might be smart
Altho should be said redis is nosql
IDK. I wouldnt use redis as storage at all, only for messaging.
Another developer on a network that I previously worked on.
Yeah I use that for pub/sub.
Ah ok
Wdym by " one by one"?
jedis.hset(key, "name", clan.getName());
jedis.hset(key, "tag", clan.getTag());
.... and others
vs
jedis.hset(key, "details", gson.toJson(clanObject));
Yes, I think I use both on pub/sub and in general.
And my friend said that If I use String Json to store it, it would make the Redis heavier.
Which I think it doesn't make sense.
Because we're storing a String, unless the length of the String matters.
Not really true
Of course storing stuff in memory requires memory
But the alternative is to store more entries
and also you don’t need json, believe jedis or well redis in general has support for maps,sets and so on
I mean, it's really easier using Gson xd, you can convert json into java object, that's pretty awesome.
It's really doesn't matter right? whether I use Gson or not, it's the same.
Yeah both work finely
Okay
@supple parrot now I'm struggling to when should I load the clans data, Clan, ClanStats and ClanBedwars.
Should I load it at the same time as we load player data?
APPLE event after player data is loaded
check if player has a clan
if player has a clan, load the clan from redis cache
if clan data on redis cache not exist
load from mysql
store it on redis cache
store it on local cache
if clan data on redis cache exist
load from redis cache
store it on local cache
Does it sound safe?
Hmm yeah
And when you update the clan data
Send and update message to other nodes
and let the other nodes re-fetch the data from REDIS/MYSQL
Gotcha. I have updated the code, feel free to give me any advice, and I'm going to sleep now. Thanks y'all.
Sounds delightful, sleep tight
I'm back and fresh, and now It's the time to create a method to create a clan, invite/kick/promote members, and changing clan data such as tag, colorTag, etc with command.
Right now I don't know how to generate uuid for the clan and making sure the generated uuid is not taken by other clan yet. I know I should use UUID#randomUUID but how do I get all existing clan uuid.
Just dont care
The chance that uuid will be the same is soo minor
Oh okay
@supple parrot how can I keep detect If the members of the clan is online or not? Should I use Redis for that too? And also for ClanChat, should I use plugin message channel or redis.
For chat i'd use Redis aswell
it is much better at messaging than bungeecord one
For online players, i'd make a plugin for bungee
How do you link it with the spigot plugin?
Hmm... Redis
Like store every player that joined on the bungee?
break down your project into bukkit and bungee module and abstrsact out platform specific stuff. Like, clans are going to exist on all servers and proxy aswell. Then, to get all online players, you send a message to bungee snd wait for response
Oh so just check If it's only requested?
Yyeah, i think? Redis is fast enough