I'm not quite sure what you're trying to show. We are well aware that
the number of items you can keep in memory is limited by the available
memory. We are also well aware that gc costs increase as memory usage
goes up.
This was all known when HAppS development started. We realised that
limited memory capacity wasn't the only problem. You also have to deal
with reliability. Since few would consider running their production
system without backups or failovers, we decided to resolve all of
these issues in a unified manner. That is, by running your application
across multiple machines. This way you get no single point of failure
and all the memory you can afford.
As a side note, you're filling up the memory with String's. They
require at least 12 bytes per character. Using a different
representation would be prudent.
As an additional side note, you're free to store data on disk, S3 or
anywhere else. This does not interfere with the HAppS model.
--
Cheers,
Lemmih
As Justin said, don't worry about that until it becomes a problem.
Moving stuff from memory to disk/s3 is quite easy.
>> we decided to resolve all of
>> these issues in a unified manner. That is, by running your application
>> across multiple machines. This way you get no single point of failure
>> and all the memory you can afford.
>
> I'm not sure if I understand what you're saying. Even with sharding,
> the naive approach of "everything in macid" that I used with the
> tutorial job board won't scale... correct? My understanding is that
> sharding will help you scale in terms of dealing with more user
> queries to the application, but not actually keeping more of the data
> in ram, where its easier to access than on a hard disk. Please correct
> me if I'm wrong.
Partitioning will allow you to keep subset of the data in memory. This
is different from replication which only scales w.r.t. queries.
>> As an additional side note, you're free to store data on disk, S3 or
>> anywhere else. This does not interfere with the HAppS model.
>
> Agree. I don't know why, but I've resisted this idea. I think I just
> liked the conceptual simplicity of using the macid machinery for
> everything. But I've learned my lesson. Probably in the next two
> releases I will be moving a lot of the application to the hard drive,
> and only using state for what is REALLY state. In the case of the job
> board, actually, I don't think there is any real transactional state.
> Users actions can happen in pretty much any order they want.
>
> My understanding is that with the current released version of HAppS,
> there is no support for running state across across multiple machines.
> I also understand there is some support for this in the head version
> of HAppS, and if you'll point me towards documentation or a demo of
> how this is used, I'll try and have a look. Any intuition on when
> there will be a release to hackage?
The released version already supports replication, I believe.
Partitioning, on the other hand, is still being developed privately.
When it will be released depends on funding.
>> As a side note, you're filling up the memory with String's. They
>> require at least 12 bytes per character. Using a different
>> representation would be prudent.
>
> Wow, 12 bytes. I'll definitely switch to something else. What would
> you recommend? Bytestrings?
Yeah, they're not perfect but they'll do.
--
Cheers,
Lemmih
> Partitioning will allow you to keep subset of the data in memory. This
> is different from replication which only scales w.r.t. queries.
Yeah. I actually like to think of "replication" as five distinct techniques:
1. Journaling: Replicate transactions to persistent storage. Doesn't
allow you to handle any more data, and actually slows things down
relative to not doing it, but is the simplest way to provide disaster
recovery.
2. Remoting: Move the state to another server and access it remotely.
Gives some flexibility in CPU and RAM usage.
3. Mirroring: Replicate the entire state locally on a client machine,
but still send transactions to be executed on the server. Provides
improved query speed on the client without impacting the server.
Client can also continue to run read-only if connection is lost, and
server doesn't care if connection is lost.
4. Partitioning: Split your state into multiple pieces, each of which
is transactional but which don't coordinate with each other. Allows
spreading data across multiple machines, for greater data sizes. Also,
can improve snapshot and startup times even on a single machine due to
isolation of data.
5. Clustering: Replicate the same state on multiple machines, and
coordinate them transactionally (a.k.a. "multimaster"). Provides
improved query latency but worse transaction latency (though not
necessarily reduced throughput). Most importantly, provides redundancy
such that as long as a majority of the nodes are still connected, they
can continue servicing requests.
The cool thing is they can be mixed and matched as desired -- for
example, partition the data, then deploy each partition as a cluster
with journaling on each node, and have clients access some partitions
remotely while mirroring others. And partitioning and remoting don't
even really require support from the framework itself -- just start up
multiple instances of your app and provide your own web services or
whatever.
Journaling, mirroring, and clustering need to be built-in since they
affect how transactions are handled. I can't speak to their state in
HAppS, but Prevayler has of course always had journaling and has a
reasonably functional mirroring implementation. Several people have
experimented with clustering but we haven't included an implementation
in Prevayler itself yet.
Cheers,
Justin