You’re most likely best of configuring sharding. The aggregate identifier is usually a good sharding key, as all “regular” operations on the event store always use an aggregate id. That would allow you to spread operational load over the shards.
An alternative (or something to consider in combination with sharding) is an archiving solution. For one of our clients, I have built an event store implementation that appends events as a stream in files. During normal operations, the archive is never used. The operational database would contain all events relevant to reconstruct aggregate state. Only when replaying historic data, you will need access to the archive.
Work is being done on an event store implementation that can easily handle this type of volume. It will be commercially licensed to provide a more large-scale alternative to the implementations already available in Axon. If you’re interested in such implementation, let me know and I’ll send you some information.