RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Better storage engine

Jeff

Lord
ntony;837445 said:
There maybe a slightly increase on the memory usage. But why double? How is the memory spent on? Maybe my bad English didn't explain it well.

if you have to store everything you want to save in memory, you have to duplicate each value, thus doubling your memery usage, then saving. The RunUO team looked into this as a potential storage solution, but it was not viable.
 

ntony

Sorceror
Jeff;837580 said:
if you have to store everything you want to save in memory, you have to duplicate each value, thus doubling your memery usage, then saving. The RunUO team looked into this as a potential storage solution, but it was not viable.

Sorry, maybe my explanation is not clear enough. Nope! My idea is not done in this way.
Every object which needs to be saved should inherit an interface which will provide update mask on each attribute. After object which has been updated, the updated object serial, field and value should be enqueued into process/handler. And the handler write it to update log and update it to database on FIFO basis. Checkpoints should be made on this system since there might be system crash.
This may take some more CPU clock doing this, but the game play would be seamless.
 

Lichtblitz

Sorceror
I'm not sure what Jeff referred to exactly, but your system would indeed use twice the memory.

The database is located in memory and all instantiated objects are in memory as well. You could avoid this by not instantiating any object on the internal map for example and only pull it out of the DB when it is needed. This makes no sense at all with the current architecture of RunUO. It's not designed that way and implementing a system based on a relational database that is both clever and makes sense would be a completely different server emulator. That's not generally a bad thing but it really begs the question if it's worth the effort if the system is not used by several hundred people afterwards. We all need payment - even if it's just acknowledgment.
 

Jeff

Lord
ntony;837671 said:
Sorry, maybe my explanation is not clear enough. Nope! My idea is not done in this way.
Every object which needs to be saved should inherit an interface which will provide update mask on each attribute. After object which has been updated, the updated object serial, field and value should be enqueued into process/handler. And the handler write it to update log and update it to database on FIFO basis. Checkpoints should be made on this system since there might be system crash.
This may take some more CPU clock doing this, but the game play would be seamless.
You are en-queuing a possible same number of properties each item has, for each item in the game.... how does this not double memory... I gotta stop coming to this thread...it is getting more and more ridiculous.

Also, you don't inherit an interface, you implement it. You inherit from classes.
 

Kamron

Knight
Using .NET Framework 4.0 it is possible to recode RunUO to use a cluster system with an ODBC driver and multiple machines to achieve a seamless realtime backup of the world, without stopping for world saves. I am still convinced though that a) you will need hardware beyond the reach of the average server admin and b) it will require insane amounts of coding which must be customized to every shard in order to get it to work properly. Even then, there is setup of "extra" software such as database software and maintenance. If someone is looking for a "proof of concept", then yes it is possible, I can tell you that right now without wasting another second.

Regarding the system I was talking about where each property is serialized on an as-needed basis, this would work as well in either a binary (incremental backup) or database (postgresql or oracle or ibm) setup. The required coding is still prohibitively high and impractical.

If someone made a shard that had NO houses, then you could reduce the size of the world to just players, the items in their backpack/bankbox, and their pets. That would be the most practical solution.
 

Lichtblitz

Sorceror
Kamron;837807 said:
If someone made a shard that had NO houses, then you could reduce the size of the world to just players, the items in their backpack/bankbox, and their pets. That would be the most practical solution.

Congratulations. You invented WoW ;-)
 
Lichtblitz;837821 said:
Congratulations. You invented WoW ;-)
haha

For non-custom houses, the house itself shouldn't add too much. Everything stored in the house otoh... To be fair, youd encounter the same situation to a lesser extent with bankboxes though.
 

Kamron

Knight
I am curious, why the lol? I use postgresql with MyRunUO and the custom systems I am creating for my shard. :)

I wouldn't use a database system for serializing properties/objects though... just was noting that it is possible.

Lichtblitz;837821 said:
Congratulations. You invented WoW ;-)

Yeah, I was thinking that too as I wrote it lol
 

Jeff

Lord
Kamron;837877 said:
I am curious, why the lol? I use postgresql with MyRunUO and the custom systems I am creating for my shard. :)

I wouldn't use a database system for serializing properties/objects though... just was noting that it is possible.



Yeah, I was thinking that too as I wrote it lol

Not a fan of it is all.
 

ntony

Sorceror
Lichtblitz;837681 said:
I'm not sure what Jeff referred to exactly, but your system would indeed use twice the memory.

The database is located in memory and all instantiated objects are in memory as well. You could avoid this by not instantiating any object on the internal map for example and only pull it out of the DB when it is needed. This makes no sense at all with the current architecture of RunUO. It's not designed that way and implementing a system based on a relational database that is both clever and makes sense would be a completely different server emulator. That's not generally a bad thing but it really begs the question if it's worth the effort if the system is not used by several hundred people afterwards. We all need payment - even if it's just acknowledgment.

It depends on how fast your saving engine to finish the update. If your saving process takes longer new updates moving into the queue. It may be double, triple, quadro... many many times of the memory usage.

And I agree with your second point.
 

arul

Sorceror
One solution that pays off really nice is to either:

1/ Serialize the world to a MemoryStream first, then in a background thread patiently flush the stream to a disk.
2/ Use some RamDisk tool and serialize your data to that disk.

Both ways eliminate the ultra thin HDD access bottleneck, making the save of averagely populated world almost seamless, or beyond - a little lag- feel, for a price of ~double memory usage during the save period (the save duration depends highly on how much is the I/O thread(s) slacking off).
 

ntony

Sorceror
arul;839011 said:
One solution that pays off really nice is to either:

1/ Serialize the world to a MemoryStream first, then in a background thread patiently flush the stream to a disk.
2/ Use some RamDisk tool and serialize your data to that disk.

Both ways eliminate the ultra thin HDD access bottleneck, making the save of averagely populated world almost seamless, or beyond - a little lag- feel, for a price of ~double memory usage during the save period (the save duration depends highly on how much is the I/O thread(s) slacking off).

have you tried to write your save data onto ramdisk yet? did it dramatically drop your save time?
 

arul

Sorceror
ntony;839251 said:
have you tried to write your save data onto ramdisk yet? did it dramatically drop your save time?
Yes, tried it with Superspeed Ramdisk Plus 9.0 x64. It merely eliminated my save time :)

 

DerrickUOSA

Wanderer
Has this RamDisk solution worked out in the long run?

An order of magnitude gain in save times would really be nice, and I'm hoping that using a RamDrive might provide that.

As mentioned earlier differential saves make me nervous as well. I've never done any testing but it has been my suspicion that the real bottleneck in saves is write speed.

I absolutely love the RunUO serialization, and the absolute integrity/consistency provided by it. It's very well optimized and blazingly fast for what it's doing (RunUO 2.0 ).

I've done a lot of optimizing of the item and mobile serialization (mostly removal of AoS data), but in the end the modifications were not really worth the time, and only served to make my codebase more incompatible with the trunk :/

Possible rambling:
One other solution that I'd been considering is a region by region save. That is, lock each region sequentially and save it; I'm not sure if the overhead that would be involved in preventing updates, or enters/exits to mobiles in that region would overcome the gains though. Another thought I had was to lock the internal map and save it first, in some other (likely complex) form of locking scheme. Neither of these solutions would be very easy, the latter probably addresses the problem best, as in my experience anyway the far majority of objects reside on the internal map (logged out players equip, banks).

Humbly, I think the rule of thumb that the simpler code is the better code (even if it's slower) really applies here, as there is nothing more critical to a UO shard than its data.
 

Jeff

Lord
The new DynamicSaveStrategy seems to reduces save time by roughly 50% in testing, and with SSD drives, you can reduce it even more I'm sure.
 

DerrickUOSA

Wanderer
Ahh, thanks much. I feel a little outdated :)

If I can get this up and running I'll post results. Sounds like DynamicSaveStrategy may make this problem obsolete for many.
 

Tartaros

Wanderer
how is the dynamic save strategy different from the old one?

Also, did someone consider using a NoSQL database for this? Seems to me it would be ideally suited for storing a lot of
 

Jeff

Lord
DynamicSaveStrategy uses .Net 4.0 TPL to asynchronously write data to the disk,where-as Standard and Dual SaveStrategies write synonymously, causing a blocking operation which locks the server. The Dynamic strategy does cause a block initially to basically write the save in memory, but then releases while it saves to disk in the background.

As for the NoSQL option, this would require much more advanced knowledge then most of our current users have, not to mention the increase in learning curve... The upkeep alone for databases would be to much hassle imo.
 
Top