About Game Cache

original
2015/08/05 19:21
Reading number 771

1. Local cache and distributed cache

In order to ensure the performance of accessing data, the game server needs to cache the player's data. According to different cache locations, the game server can be divided into local jvm cache and distributed cache. I have been exposed to two kinds of games before.

      Local jvm cache: There are many ways to implement it. A better way is to use some third-party caches, such as ehcache, which provide a variety of cache strategies, or Implement a local cache by yourself, such as through ConcurrentHashMap.

      Distributed cache: Redis has been contacted before, and the server side is also supported after Redis 3.0 Implement clusters.
(More http://my.oschina.net/OutOfMemory/blog/412408 )

2. Cache and database

Some games may regard the cache as a cache. When getting, they first take data from the cache and then put it into the cache. When updating and deleting are really needed, they directly operate the database. I think this method is a compromise, which guarantees certain performance and security.

The other situation is that everything is done in the cache, and then synchronized to the database regularly. This situation has a certain risk, resulting in cache data not synchronized to the database. Of course, if you use a cache like Redis, it provides two persistence functions, namely RDB and AOF. In fact, data loss may also occur in RDB mode.

Game companies feel that they pay more attention to performance. Sometimes they don't pay special attention to data security, but they can tolerate data loss (game file back). Anyway, I don't particularly agree with this, but the fact is that many companies do this.

3. Data synchronization

        The synchronization of local cache has been realized in two ways. One is to put all the addition, deletion and modification operations into the queue in order, and then use the timer to read the queue and synchronize the data to the database; The other is to check whether the object has changed through CRC32, and then synchronize.

Let's see an example of CRC32

 public class CRC32Util { /** *Get the crc value of the object *  * @param object *Objects that implement the Serializable interface * @return */ public static long getCRC(Object object) { long crc = 0; CRC32 crc32 = new CRC32(); crc32.update(object2Byte(object)); crc = crc32.getValue(); return crc; } /** *Turning Serializable Objects into Byte Arrays *  * @param object *Objects that implement the Serializable interface * @return */ public static byte[] object2Byte(Object object) { byte data[] = null; ObjectOutputStream out = null; ByteArrayOutputStream baos = null; try { baos = new ByteArrayOutputStream(); out = new ObjectOutputStream(baos); out.writeObject(object); data = baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); } finally { if (out !=  null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } if (baos !=  null) { try { baos.close(); } catch (IOException e) { e.printStackTrace(); } } } return data; } }
 public class BagCache implements Serializable { private static final long serialVersionUID = 1L; private long id; private int pid; private int num; public BagCache(long id, int pid, int num) { this.id = id; this.pid = pid; this.num = num; } //Get.set method }
 public class RoleCache implements Serializable { private static final long serialVersionUID = 1L; private int roleId; private String roleName; private Map<Long, BagCache> bagMap = new HashMap<Long, BagCache>(); public RoleCache(int roleId, String roleName) { this.roleId = roleId; this.roleName = roleName; } public BagCache getBag(long id) { return bagMap.get(id); } public void putBag(BagCache bag) { bagMap.put(bag.getId(), bag); } //Get.set method }
 public class CRC32Test { public static void main(String[] args) { RoleCache role = new RoleCache(1, "a1"); BagCache bag = new BagCache(1, 1, 1); role.putBag(bag); long crc = CRC32Util.getCRC(role); System. out. println ("first time:"+crc); role.setRoleName("a2"); crc = CRC32Util.getCRC(role); System. out. println ("the second time:"+crc); bag.setNum(2); crc = CRC32Util.getCRC(role); System. out. println ("the third time:"+crc); } }

Pass regular check Serializable CRC32 value of the memory object to determine whether the current object needs to be synchronized.

For distributed cache, because it supports persistence itself, in many cases you don't need to do persistence yourself, such as mogodb; Of course, the problem is that caching databases such as Redis and mogodb are not particularly convenient for us to do data statistics, so we often use Redis+MySQL to synchronize data into MySQL, on the one hand for security, and on the other hand for data statistics. The idea of synchronizing Redis to MySQL is similar. Add, delete, and modify keys into the set list of Redis, and then the timer reads the set list to synchronize MySQL.

Expand to read the full text
Loading
Click to join the discussion 🔥 (1) Post and join the discussion 🔥
Reward
one comment
eight Collection
zero fabulous
 Back to top
Top