MySQL 单表插入 10w+ TPS达成(3)

发表于:2013-12-27来源:IT博客大学习作者:淘宝文通点击数: 标签:MySQL
* @since 12-2-9 下午3:31 * */ int step = 100000000 int index = Integer .valueOf(args[0]) AtomicLong id = new AtomicLong((index - 1) * step + 1) TDHSClient client = new TDHSClientImpl( new InetSocket

     * @since 12-2-9 下午3:31

     *

     */

    

     int step = 100000000

    

     int index = Integer.valueOf(args[0])

    

     AtomicLong id = new AtomicLong((index - 1) * step + 1)

    

     TDHSClient client = new TDHSClientImpl(new InetSocketAddress("10.232.31.25", 9999), 2);

    

     def s = new StressTest(count: step)

     s.add({

     def _id = id.incrementAndGet()

     String table = "test"

     TDHSResponse response = client.createStatement(index).insert().use("benchmark_insert").from(table)

     .value("id", _id.toString())

     .value("k", "10000")

     .value("i", _id.toString())

     .value("c", _id.toString() + "_abcdefghijklmnopqrstuvwxyz").insert()

    

     if (response != null && response.getStatus() != TDHSResponseEnum.ClientStatus.OK) {

     System.out.println(response);

     }

     }, 100)

    

     s.run()

     client.shutdown()

  使用TDH_SOCKET进行插入能到这么高TPS的关键:

  TDH_SOCKET提供group commit:

  减少redo log的fsync次数,使IOPS不成为瓶颈

  TDH_SOCKET能提供并发写.

  自增id的生成策略需要分段自增:

  如果采用全自增id生成策略(即默认innodb提供的自增id生成策略)的话,会在高并发插入的时候遇到一个block的写锁.

  因为是顺序自增,所以并发插入的记录都会集中写入到同一个page上,而一个线程写page会对这个page做一次 rw_lock_x_lock_func(&(block->lock), 0, file, line); 那么这个写锁会成为瓶颈,使TPS无法上去所以只要改变生成id的策略:

  分段自增比如一个写线程一下子获取1-10000的id范围 下一个写线程获取10001-20000的id范围..

  每个写线程在各自的范围里面自增的生成id,那么即能保证一定的顺序写,又能使写page不会因为并发写锁而性能下降!

  至于TDH_SOCKET是啥…..先买个关子~

原文转自:http://blogread.cn/it/article/5070

...