【问题标题】:Prevayler Serialization OptimizationPrevayler 序列化优化
【发布时间】:2013-08-20 13:26:22
【问题描述】:

我正在与 Prevayler 合作,进行一些非常简单的压力测试。

在我的程序中,我可以在 500 毫秒内获得 10,000 次读取,但写入或更改一个对象需要 23 毫秒。 (我没有这台电脑的详细规格。没什么令人印象深刻的。双核 3.0ghz,7200rpm HD,可能还有 1333mhz ddr3 内存。)

序列化似乎是瓶颈。

可以做些什么来提高写入/更改性能?

JProfiler 我在 JProfiler 中运行程序(将 10,000 个用户对象写入磁盘。),它运行了 250 秒,其中 99.6% 用于运行 org.implementation.PrevaylerImpl.execute

更新 我切换到 XStreamSerializer,它将写入速度提高到每次写入 21 毫秒,并减少了存储空间

3555KB 日志/10,000 个对象 -> 2421KB

350KB 快照/10,000 个对象 -> 313KB

我希望看到 1000+ 次写入/秒。

---- Main Method ----

Transactor trans = new Transactor();

    for(int i =0;i<10000;i++)
    {
       trans.createUser("Username", "PasswordHash");
    }  


---- Transactor Class ----

public void createUser(String Username, String PasswordHash) {    

    String id = Helper.randomID();

    //Avoids id duplicates, id is 7 digit base58. (Like Bitcoin, but shorter.)
    //ID generation takes .0078ms.
    while(getUser(id)!=null)
    {
        id=Helper.randomID();
    }

    prevayler.execute(new CreateUser(Username, PasswordHash,id));
}


---- CreateUser Class ----

public class CreateUser implements Transaction, Serializable{

    String Username;
    String PasswordHash;
    String id;

    public  CreateUser(String Username, String PasswordHash, String id)
    {
        this.Username = Username;
        this.PasswordHash = PasswordHash;
        this.id = id;
    }

    public void executeOn(Object core,Date date) {
          ((Core)core).store(new User(Username, PasswordHash), id);
    }
}


---- Core Class (Store method) ----

private final Map<String,Object> dataMap = new HashMap<String,Object>();

public void store(Object object, String id) {

    dataMap.put(id, object);

    //Adds User id to a seperate ArrayList<String>
    if(object instanceof User )
    {
      userList.add(id);
    }
}

【问题讨论】:

  • 能否请您格式化代码?我很难阅读您的代码。课堂在哪里? CreateUser 是内部类吗?你在序列化什么类?
  • CreateUser 最初是一个内部类,只是为了我自己的方便,它是被序列化的。 Prevayler 使用“executeOn”方法将事务序列化到磁盘。我做了一些更改,现在更容易阅读了吗?
  • 我可能会编写一个小测试用例并使用分析器来检查问题的真正原因。
  • 在您开始此测试时,您的事务日志是否为空?
  • 杂志?我开始的时候是空的,最后是 3555kb。

标签: java database serialization throughput prevayler


【解决方案1】:

23ms 大约适合一个旋转磁盘。使用 Disc Sync,我猜想打开一个文件,记录事务,刷新到磁盘并关闭文件。如果磁盘磁头必须为此移动(例如更新目录信息),您可以查看这些时间。对磁盘扇区的随机访问大约需要 20 毫秒,也许是最高端驱动器的一半。

通常最好每秒刷新 10 次,然后您可以使用足够大的磁盘扇区来容纳多个事务,并且磁盘非常擅长写入连续数据,即日志。

【讨论】:

    【解决方案2】:

    我关闭了磁盘同步(默认情况下处于打开状态。),现在我在这台计算机上获得了 2500 次写入/秒。使用 SSD,我获得了 10,000 次写入/秒。 (读取速度也快得多。) 这对我有用,但我不确定为什么磁盘同步会减慢它的速度,也许有人可以说一下?

    public Transactor() {
    
        if (prevayler == null) {
            try {
    
                PrevaylerFactory<Core> factory = new PrevaylerFactory<Core>();
                factory.configurePrevalentSystem(new Core());
    
                //This
                factory.configureJournalDiskSync(false);
    
                factory.configureJournalSerializer("Journal",new XStreamSerializer());
                prevayler = factory.create();
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多