Apache Ignite 与 SQL Server 性能

FP9*_*P93 1 in-memory-database ignite

我们正在考虑使用内存数据库(例如 Apache Ignite)来处理性能密集的类 BI 操作。因此,作为(非常原始的)示例,我用来自 csv 文件(14 列)的 250.000 条记录填充了 Apache Ignite,并执行了一些分组操作。以前,我还使用相同的数据对 MS SQL-Server 进行了一些性能测试。

有趣且出乎意料的是,MS SQL-Server 需要大约 0.25 秒来执行此操作,而使用 Apache Ignite 则需要 1-2 秒。

1,我一直认为Apache Ignite不仅是分布式计算的好选择,而且由于其面向内存的架构,与传统关系数据库相比,性能也有所提升。真的吗?为什么在我的例子中这么慢?

2、我是否以错误的方式使用了 Apache Ignite 或者我应该使用一些额外的调整选项吗?

这是我在示例中使用的源代码:

  private static Connection conn = null;
  private static Statement stmt = null;
  private static ResultSet rs = null;

  private static void initialize() throws ClassNotFoundException, SQLException

  {

       // Register JDBC driver.
    Class.forName("org.apache.ignite.IgniteJdbcThinDriver");

    // Create database tables.
    stmt = conn.createStatement();

    // Create table
    stmt.executeUpdate("CREATE TABLE PIVOT_TEST (" +
    " REGION VARCHAR, COUNTRY VARCHAR, ITEM_TYPE VARCHAR, SALES_CHANNEL VARCHAR, ORDER_PRIORITY VARCHAR, ORDER_DATE VARCHAR, ORDER_ID VARCHAR PRIMARY KEY, "
    + "SHIP_DATE VARCHAR, UNITS_SOLD NUMERIC, UNIT_PRICE NUMERIC, UNIT_COST NUMERIC, TOTAL_REVENUE NUMERIC, TOTAL_COST NUMERIC, TOTAL_PROFIT NUMERIC )");

  }



  private static void fill() throws ClassNotFoundException, SQLException
  {
        // Register JDBC driver
        Class.forName("org.apache.ignite.IgniteJdbcThinDriver");

        // Populate table
        PreparedStatement stmt =
        conn.prepareStatement("COPY FROM 'LINK_TO_CSV_FILE'" +

        "INTO PIVOT_TEST (REGION , COUNTRY , ITEM_TYPE , SALES_CHANNEL , ORDER_PRIORITY , ORDER_DATE , ORDER_ID , SHIP_DATE , UNITS_SOLD , UNIT_PRICE , UNIT_COST , TOTAL_REVENUE , TOTAL_COST , TOTAL_PROFIT ) FORMAT CSV");
        stmt.executeUpdate();

        stmt = conn.prepareStatement("CREATE INDEX index_name ON PIVOT_TEST(COUNTRY)");
        stmt.executeUpdate();
  }



  private static void getResult() throws ClassNotFoundException, SQLException
  {
        // Register JDBC driver
        Class.forName("org.apache.ignite.IgniteJdbcThinDriver");

        // Get data
        stmt = conn.createStatement();

        rs =
            stmt.executeQuery("SELECT AVG(UNIT_PRICE) AS AVG_UNIT_PRICE, MAX(UNITS_SOLD) AS MAX_UNITS_SOLD, SUM(UNIT_COST) AS SUM_UNIT_COST, AVG(TOTAL_REVENUE) AS AVG_TOTAL_REVENUE , AVG(TOTAL_COST) AS AVG_TOTAL_COST, AVG(TOTAL_PROFIT) as AVG_TOTAL_PROFIT  FROM PIVOT_TEST GROUP BY COUNTRY;");

        retrieveResultSet();      

  }



  private static void retrieveResultSet() throws SQLException
  {
        while (rs.next())
        {
                for(int i=0; i<rs.getMetaData().getColumnCount(); i++)
                {
                    rs.getObject(i+1);
                }
        }
  }



  public static void main(String[] args) throws SQLException, ClassNotFoundException

  {

        Ignite ignite = null;

        try

        {

            //--------------------------------CONNECTION-------------------//

            IgniteConfiguration configuration = new IgniteConfiguration();

            ignite = Ignition.start(configuration);

            conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1/");

            initialize();

            fill();


            long endPrepTable = System.currentTimeMillis();

            getResult();

            long endGetResult = System.currentTimeMillis();

            System.out.println("Get Result (s)" + " " + (endGetResult - endPrepTable)*1.0/1000);

        }

        catch(Exception e)
        {
            e.printStackTrace();
        }

        finally
        {
          ignite.close();

          conn.close();

          rs.close();
        }

  }
Run Code Online (Sandbox Code Playgroud)

感谢您的帮助!

dma*_*gda 5

将 Ignite 与关系数据库进行比较时,需要考虑以下几点:

  • Ignite SQL 引擎针对以 RAM 作为主存储的多节点部署进行了优化。不要尝试将单节点 Ignite 集群与针对此类配置优化的关系数据库进行比较。部署一个多节点集群,并在 RAM 中提供完整的数据副本。
  • 在数据建模和优化过程中考虑基本建议,例如关联搭配、二级索引和此处列出的其他建议。
  • 另外,请记住,关系数据库利用本地缓存技术并取决于总数据大小,并且在多节点配置中,一种查询可以比 Ignite 更快地完成某些查询。例如,我看到 SQL 服务器在 5 毫秒内完成以下查询,而 Ignite 单节点集群在 8 毫秒内完成,4 节点集群在 20 毫秒内完成:

    SELECT * FROM Input i JOIN Party pr ON (pr.prt_id) = (i.mbr_id) order by i.input_id offset 0 limit 100

    这是预期的,因为数据集大小约为 64GB,并且 SQL Server 可以在本地 RAM 中缓存很多。此外,与单节点集群相比,节点内通信的成本影响了 4 节点集群的数量。

    要释放分布式内存计算的强大功能,请通过检查更复杂的查询(如下所示)将更多数据预加载到集群或/并强制 SQL Server 转到磁盘:

    SELECT * FROM Input i INNER JOIN Product p ON (i.product_id) = (p.product_id) INNER JOIN Party pr ON (pr.prt_id) = (i.mbr_id) and (pr.session_id=i.session_id) WHERE I. PRODUCT_ID=5 和 I.SOURCE_ID=6

    在我的例子中,SQL Server 在相同的配置和 64GB 的数据中完成查询需要 510 秒(它必须转到磁盘)。Ignite 的 4 节点集群在 32 秒内完成,8 节点集群在 8 秒内完成。