前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenSSL与yaSSL性能对比

OpenSSL与yaSSL性能对比

作者头像
腾讯数据库技术
发布2018-11-06 20:23:31
3K1
发布2018-11-06 20:23:31
举报
文章被收录于专栏:腾讯数据库技术

摘要

MySQL可以使用OpenSSL或yaSSL/wolfSSL进行编译,这两者都支持基于OpenSSL API的加密连接。在5.7版本,我们知道默认情况下MySQL Community Edition用的SSL库是yaSSL,而在8.0版本,MySQL Community Edition用的是OpenSSL。那么SSL加密对性能有什么影响呢?这两个SSL库在性能上又到底有多大差别呢?我们接下来进行一些测试并进行分析。

测试内容

MySQL有两个功能使用到了SSL库,一个是SSL连接,通过在数据库服务器与客户端应用程序之间强制实施SSL连接,可以加密服务器与应用程序之间的数据流,有助于防止“中间人”攻击;还有一个是透明加密,通过对存储的数据进行加密,来保证数据的安全。因此我们测试采用两个测试组来分别对这两个功能进行测试。测试采用sysbench执行oltp系列场景对应脚本。

测试环境

1 SSL连接测试组

2 透明加密测试组

1 SSL连接测试组测试步骤

  1. 安装并初始化mysql,将数据目录设定在测试的SSD盘上;
  2. 主备机按照异步备方式连接; 密钥生成说明:本次测试使用openssl生成长度为2048的非对称密钥(rsa-2048),生成方式如下: #生成根密钥 $ openssl genrsa 2048 > ca-key.pem #生成根证书 $ openssl req -new -x509 -nodes -days 3600 -key ca-key.pem -out ca.pem #生成服务器证书请求,用以生成服务器密钥、证书 $ openssl req -newkey rsa:2048 -days 3600 -nodes -keyout server-key.pem -out server-req.pem #生成服务器密钥(私钥) $ openssl rsa -in server-key.pem -out server-key.pem #生成服务器证书(公钥,x509格式封装) $ openssl x509 -req -in server-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem #生成客户端证书请求,用以生成服务器密钥、证书 $ openssl req -newkey rsa:2048 -days 3600 -nodes -keyout client-key.pem -out client-req.pem #生成客户端密钥(私钥) $ openssl rsa -in client-key.pem -out client-key.pem #生成客户端证书(公钥,x509格式封装) $ openssl x509 -req -in client-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
  3. 启动mysqld服务;
  4. 分别对oltp_delete、oltp_insert、oltp_point_select、oltp_read_only、oltp_read_write、oltp_update_index、oltp_update_non_index、oltp_write_only、 select_random_points、select_random_ranges这11个测试模型运行以下命令: $ export LD_LIBRARY_PATH=/***/***/lib $ sysbench --tables=100 --table-size=4000000 --threads=50 --mysql-db=sbtest --mysql-user=root --time=300 oltp_delete --mysql-password=root --mysql-host=***.***.***.*** prepare $ date $ sysbench --tables=100 --table-size=4000000 --threads=50 --mysql-db=sbtest --mysql-user=root --time=300 oltp_delete --mysql-password=root --mysql-host=***.***.***.*** run $ date $ sysbench --tables=100 --table-size=4000000 --threads=50 --mysql-db=sbtest --mysql-user=root --time=300 oltp_delete --mysql-password=root --mysql-host=***.***.***.*** cleanup
  5. 执行以下命令收集sysbench执行run过程中的io数据、cpu数据、perf数据以及堆栈信息; $ iostat -t 2 -c -d -x /dev/*** > iostat.log $ perf top -p mysqld_process_id $ pt-pmp -p mysqld_process_id > ptpmp.log
  6. 不启用SSL时,在配置文件中添加如下配置并重启mysqld; skip_ssl=on
  7. 短连接测试。运行N个进程,每个进程独立执行M次mysql命令,每个命令都是建立连接-运行-断开连接模式。由于sysbench不支持该模型,用shell脚本编写上述测试模型进行测试,脚本自动生成日志,记录连接成功与否、记录perf record信息。脚本在nossl执行后立即切换到ssl状态继续执行,一共执行2次:第一次是20个进程,每个进程执行10000次insert && select count(*)语句,配置参数max_connections设置为150(默认);第二次是100个进程,每个进程执行1000次mysql连接,不执行任何语句,每次短连接运行脚本,配置参数max_connections设置为10000。第一次短连接运行脚本为: $ mysql -e "use sbtest;insert into connectTest values(a);select count(*) from connectTest;"

2 透明加密测试组

  1. 安装并初始化mysql,将数据目录设定在测试的SSD盘上;
  2. 启动mysqld服务;
  3. 依次测试oltp_delete、oltp_insert、oltp_point_select、oltp_read_only、oltp_read_write、oltp_update_index、oltp_update_non_index、oltp_write_only、select_random_points、select_random_ranges、bulk_insert这11个场景,执行以下命令测试性能: $ export LD_LIBRARY_PATH=******** $ sysbench --tables=100 --table-size=4000000 --threads=50 --mysql-db=sbtest --mysql-user=root --mysql-socket=/***/mysql.sock --time=300 oltp_delete prepare $ mysql -uroot -S /***/mysql.sock -e "alter table sbtest1 encryption='Y'" sbtest #加密场景需额外执行该SQL命令将所有测试表进行加密。 $ sysbench --tables=100 --table-size=4000000 --threads=50 --mysql-db=sbtest --mysql-user=root --mysql-socket=/***/mysql.sock --time=300 oltp_delete run $ sysbench --tables=100 --table-size=4000000 --threads=50 --mysql-db=sbtest --mysql-user=root --mysql-socket=/***/mysql.sock --time=300 oltp_delete cleanup
  4. 执行以下命令收集sysbench执行run过程中的io数据、cpu数据、perf数据以及堆栈信息。 $ iostat -t 2 -c -d -x /dev/*** > iostat.log $ perf top -p mysqld_process_id $ pt-pmp -p mysqld_process_id > ptpmp.log

测试结果及分析

1 SSL连接测试组

下表是部分场景中TPS性能上面的差别。

在大部分场景中(oltp_delete,oltp_insert,oltp_update_index,oltp_update_non_index, oltp_write_only, select_random_points, select_random_ranges),配置yaSSL与不配置SSL的性能在TPS表现差别不大,性能差别在5%以内,不作为关注的重点;在部分测试场景(oltp_point_select、oltp_read_only、oltp_read_write)配置SSL对性能影响较大,分别有26.03%,43.29%,29.18%的性能下降。

具体原因分析:

对txsql进行perf分析,发现oltp_point_select、oltp_read_only、oltp_read_write这三个场景导致性能下降的热点是加解密过程,以性能下降最为明显的oltp_read_only场景为例,下图所示perf热点分析对比:

带SSL的热点主要在以下两个函数:

代码语言:javascript
复制
TaoCrypt::AES::encrypt(unsigned char const*, unsigned char const*, unsigned char*) const
TaoCrypt::SHA::Transform()

经过对sysbench脚本分析,只有oltp_point_select、oltp_read_only、oltp_read_write这三个场景用到了execute_point_selects() 这个测试模型,而且性能差异明显的oltp_read_only场景中,仅仅跑了oltp_read_only这一个模型。这个模型仅调用”SELECT c FROM sbtest%u WHERE id=?” ,客户端在查询后立即执行,因此数据库对每次查询都是立即返回,不会做batch,数据库返回数据次数增加,增多对小数据的加密,增加加密次数,因此性能差异明显体现。

对比OpenSSL和yaSSL的数据(仅测试3个SSL影响较大的场景),总体上看OpenSSL比yaSSL性能高一点。oltp_select_point场景有点异常,性能低很多。

查看perf对比数据:

很明显加密后出现一个热点。使用pt-pmp工具查看对应的堆栈:

代码语言:javascript
复制
    Mon Jul 23 14:24:07 CST 2018
    28 pthread_rwlock_rdlock(libpthread.so.0),native_rw_rdlock(thr_rwlock.h:79),inline_mysql_rwlock_rdlock(thr_rwlock.h:79),openssl_lock(thr_rwlock.h:79),openssl_lock_function(thr_rwlock.h:79),int_thread_get_item(libcrypto.so.10),ERR_get_state(libcrypto.so.10),get_error_values(libcrypto.so.10),SSL_get_error(libssl.so.10),ssl_should_retry(viossl.c:133),vio_ssl_read(viossl.c:133),net_read_raw_loop(net_serv.cc:672),net_read_packet_header(net_serv.cc:756),net_read_packet(net_serv.cc:756),my_net_read(net_serv.cc:899),Protocol_classic::read_packet(protocol_classic.cc:808),Protocol_classic::get_command(protocol_classic.cc:965),do_command(sql_parse.cc:965),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)
    10 __io_getevents_0_4,LinuxAIOHandler::collect(os0file.cc:2500),LinuxAIOHandler::poll(os0file.cc:2646),os_aio_linux_handler(os0file.cc:2702),os_aio_handler(os0file.cc:2702),fil_aio_wait(fil0fil.cc:5906),io_handler_thread(srv0start.cc:311),start_thread(libpthread.so.0),clone(libc.so.6)
    8 pread64(libpthread.so.0),execute(os0file.cc:2179),os_file_io(os0file.cc:2179),os_file_pread(os0file.cc:5644),os_file_read_page(os0file.cc:5644),os_file_read_func(os0file.cc:6076),os_aio_func(os0file.cc:6076),pfs_os_aio_func(os0file.ic:261),fil_io(os0file.ic:261),buf_read_page_low(buf0rea.cc:183),buf_read_page(buf0rea.cc:183),buf_page_get_gen(buf0buf.cc:4196),btr_cur_search_to_nth_level(btr0cur.cc:1107),btr_pcur_open_with_no_init_func(btr0pcur.ic:521),row_search_mvcc(row0sel.cc:5091),ha_innobase::index_read(ha_innodb.cc:8770),handler::index_read_idx_map(handler.cc:7503),handler::ha_index_read_idx_map(handler.cc:3082),read_(handler.cc:3082),join_read_const_table(handler.cc:3082),JOIN::extract_func_dependent_tables(sql_optimizer.cc:5579),JOIN::make_join_plan(sql_optimizer.cc:5043),JOIN::optimize(sql_optimizer.cc:368),st_select_lex::optimize(sql_select.cc:1009),handle_query(sql_select.cc:164),execute_sqlcom_select(sql_parse.cc:5247),mysql_execute_command(sql_parse.cc:2851),Prepared_statement::execute(sql_prepare.cc:3935),Prepared_statement::execute_loop(sql_prepare.cc:3543),mysqld_stmt_execute(sql_prepare.cc:2549),dispatch_command(sql_parse.cc:1437),do_command(sql_parse.cc:1023),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)
    3 pthread_cond_wait,wait(os0event.cc:165),wait_low(os0event.cc:165),os_event_wait_low(os0event.cc:165),srv_worker_thread(srv0srv.cc:2528),start_thread(libpthread.so.0),clone(libc.so.6)
    3 pthread_cond_wait,wait(os0event.cc:165),wait_low(os0event.cc:165),os_event_wait_low(os0event.cc:165),buf_flush_page_cleaner_worker(buf0flu.cc:3496),start_thread(libpthread.so.0),clone(libc.so.6)
    2 pthread_cond_wait,wait(os0event.cc:165),wait_low(os0event.cc:165),os_event_wait_low(os0event.cc:165),sync_array_wait_event(sync0arr.cc:475),rw_lock_x_lock_func(sync0rw.cc:795),pfs_rw_lock_x_lock_func(sync0rw.ic:705),btr_search_x_lock(sync0rw.ic:705),btr_search_info_update_slow(sync0rw.ic:705),btr_search_info_update(btr0sea.ic:81),btr_cur_search_to_nth_level(btr0sea.ic:81),btr_pcur_open_with_no_init_func(btr0pcur.ic:521),row_search_mvcc(row0sel.cc:5091),ha_innobase::index_read(ha_innodb.cc:8770),handler::index_read_idx_map(handler.cc:7503),handler::ha_index_read_idx_map(handler.cc:3082),read_(handler.cc:3082),join_read_const_table(handler.cc:3082),JOIN::extract_func_dependent_tables(sql_optimizer.cc:5579),JOIN::make_join_plan(sql_optimizer.cc:5043),JOIN::optimize(sql_optimizer.cc:368),st_select_lex::optimize(sql_select.cc:1009),handle_query(sql_select.cc:164),execute_sqlcom_select(sql_parse.cc:5247),mysql_execute_command(sql_parse.cc:2851),Prepared_statement::execute(sql_prepare.cc:3935),Prepared_statement::execute_loop(sql_prepare.cc:3543),mysqld_stmt_execute(sql_prepare.cc:2549),dispatch_command(sql_parse.cc:1437),do_command(sql_parse.cc:1023),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)
    2 pthread_cond_wait,wait(os0event.cc:165),wait_low(os0event.cc:165),os_event_wait_low(os0event.cc:165),sync_array_wait_event(sync0arr.cc:475),rw_lock_s_lock_spin(sync0rw.cc:425),rw_lock_s_lock_func(sync0rw.ic:433),pfs_rw_lock_s_lock_func(sync0rw.ic:433),btr_search_drop_page_hash_index(sync0rw.ic:433),buf_LRU_free_page(buf0lru.cc:2062),buf_LRU_free_from_common_LRU_list(buf0lru.cc:1078),buf_LRU_scan_and_free_block(buf0lru.cc:1078),buf_LRU_get_free_block(buf0lru.cc:1353),buf_page_init_for_read(buf0buf.cc:5145),buf_read_page_low(buf0rea.cc:149),buf_read_page(buf0rea.cc:149),buf_page_get_gen(buf0buf.cc:4196),btr_cur_search_to_nth_level(btr0cur.cc:1107),btr_pcur_open_with_no_init_func(btr0pcur.ic:521),row_search_mvcc(row0sel.cc:5091),ha_innobase::index_read(ha_innodb.cc:8770),handler::index_read_idx_map(handler.cc:7503),handler::ha_index_read_idx_map(handler.cc:3082),read_(handler.cc:3082),join_read_const_table(handler.cc:3082),JOIN::extract_func_dependent_tables(sql_optimizer.cc:5579),JOIN::make_join_plan(sql_optimizer.cc:5043),JOIN::optimize(sql_optimizer.cc:368),st_select_lex::optimize(sql_select.cc:1009),handle_query(sql_select.cc:164),execute_sqlcom_select(sql_parse.cc:5247),mysql_execute_command(sql_parse.cc:2851),Prepared_statement::execute(sql_prepare.cc:3935),Prepared_statement::execute_loop(sql_prepare.cc:3543),mysqld_stmt_execute(sql_prepare.cc:2549),dispatch_command(sql_parse.cc:1437),do_command(sql_parse.cc:1023),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)
    1 ut_delay(libc.so.6),rw_lock_s_lock_spin(sync0rw.cc:355),rw_lock_s_lock_func(sync0rw.ic:433),pfs_rw_lock_s_lock_func(sync0rw.ic:433),btr_search_drop_page_hash_index(sync0rw.ic:433),buf_LRU_free_page(buf0lru.cc:2062),buf_LRU_free_from_common_LRU_list(buf0lru.cc:1078),buf_LRU_scan_and_free_block(buf0lru.cc:1078),buf_LRU_get_free_block(buf0lru.cc:1353),buf_page_init_for_read(buf0buf.cc:5145),buf_read_page_low(buf0rea.cc:149),buf_read_page(buf0rea.cc:149),buf_page_get_gen(buf0buf.cc:4196),btr_cur_search_to_nth_level(btr0cur.cc:1107),btr_pcur_open_with_no_init_func(btr0pcur.ic:521),row_search_mvcc(row0sel.cc:5091),ha_innobase::index_read(ha_innodb.cc:8770),handler::index_read_idx_map(handler.cc:7503),handler::ha_index_read_idx_map(handler.cc:3082),read_(handler.cc:3082),join_read_const_table(handler.cc:3082),JOIN::extract_func_dependent_tables(sql_optimizer.cc:5579),JOIN::make_join_plan(sql_optimizer.cc:5043),JOIN::optimize(sql_optimizer.cc:368),st_select_lex::optimize(sql_select.cc:1009),handle_query(sql_select.cc:164),execute_sqlcom_select(sql_parse.cc:5247),mysql_execute_command(sql_parse.cc:2851),Prepared_statement::execute(sql_prepare.cc:3935),Prepared_statement::execute_loop(sql_prepare.cc:3543),mysqld_stmt_execute(sql_prepare.cc:2549),dispatch_command(sql_parse.cc:1437),do_command(sql_parse.cc:1023),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)
    1 trx_commit_low(trx0trx.cc:2095),trx_commit(trx0trx.cc:2199),trx_commit_for_mysql(trx0trx.cc:2418),innobase_commit_low(ha_innodb.cc:4296),innobase_commit(ha_innodb.cc:4296),ha_innobase::external_lock(ha_innodb.cc:15748),handler::ha_external_lock(handler.cc:7892),unlock_external(lock.cc:667),mysql_unlock_tables(lock.cc:416),mysql_unlock_some_tables(lock.cc:431),JOIN::optimize(sql_optimizer.cc:412),st_select_lex::optimize(sql_select.cc:1009),handle_query(sql_select.cc:164),execute_sqlcom_select(sql_parse.cc:5247),mysql_execute_command(sql_parse.cc:2851),Prepared_statement::execute(sql_prepare.cc:3935),Prepared_statement::execute_loop(sql_prepare.cc:3543),mysqld_stmt_execute(sql_prepare.cc:2549),dispatch_command(sql_parse.cc:1437),do_command(sql_parse.cc:1023),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)

大部分连接在等待一个读锁,这个锁是openssl1.1.0之前的版本所要求的,由MySQL实现后通过调用api传入。我们使用openssl1.1.0h版本源码重编译一个静态库,并重新编译txsql测试这个场景。此时查看到pt-pmp工具输出堆栈为:

代码语言:javascript
复制
    Tue Jul 24 15:49:41 CST 2018
    12 pread64(libpthread.so.0),execute(os0file.cc:2179),os_file_io(os0file.cc:2179),os_file_pread(os0file.cc:5644),os_file_read_page(os0file.cc:5644),os_file_read_func(os0file.cc:6076),os_aio_func(os0file.cc:6076),pfs_os_aio_func(os0file.ic:261),fil_io(os0file.ic:261),buf_read_page_low(buf0rea.cc:183),buf_read_page(buf0rea.cc:183),buf_page_get_gen(buf0buf.cc:4196),btr_cur_search_to_nth_level(btr0cur.cc:1107),btr_pcur_open_with_no_init_func(btr0pcur.ic:521),row_search_mvcc(row0sel.cc:5091),ha_innobase::index_read(ha_innodb.cc:8770),handler::index_read_idx_map(handler.cc:7503),handler::ha_index_read_idx_map(handler.cc:3082),read_(handler.cc:3082),join_read_const_table(handler.cc:3082),JOIN::extract_func_dependent_tables(sql_optimizer.cc:5579),JOIN::make_join_plan(sql_optimizer.cc:5043),JOIN::optimize(sql_optimizer.cc:368),st_select_lex::optimize(sql_select.cc:1009),handle_query(sql_select.cc:164),execute_sqlcom_select(sql_parse.cc:5247),mysql_execute_command(sql_parse.cc:2851),Prepared_statement::execute(sql_prepare.cc:3935),Prepared_statement::execute_loop(sql_prepare.cc:3543),mysqld_stmt_execute(sql_prepare.cc:2549),dispatch_command(sql_parse.cc:1437),do_command(sql_parse.cc:1023),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)
    10 poll(libc.so.6),vio_io_wait(viosocket.c:834),vio_socket_io_wait(viosocket.c:105),vio_ssl_read(viossl.c:196),net_read_raw_loop(net_serv.cc:672),net_read_packet_header(net_serv.cc:756),net_read_packet(net_serv.cc:756),my_net_read(net_serv.cc:899),Protocol_classic::read_packet(protocol_classic.cc:808),Protocol_classic::get_command(protocol_classic.cc:965),do_command(sql_parse.cc:965),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)
    10 __io_getevents_0_4,LinuxAIOHandler::collect(os0file.cc:2500),LinuxAIOHandler::poll(os0file.cc:2646),os_aio_linux_handler(os0file.cc:2702),os_aio_handler(os0file.cc:2702),fil_aio_wait(fil0fil.cc:5906),io_handler_thread(srv0start.cc:311),start_thread(libpthread.so.0),clone(libc.so.6)
    3 pthread_cond_wait,wait(os0event.cc:165),wait_low(os0event.cc:165),os_event_wait_low(os0event.cc:165),srv_worker_thread(srv0srv.cc:2528),start_thread(libpthread.so.0),clone(libc.so.6)
    3 pthread_cond_wait,wait(os0event.cc:165),wait_low(os0event.cc:165),os_event_wait_low(os0event.cc:165),buf_flush_page_cleaner_worker(buf0flu.cc:3496),start_thread(libpthread.so.0),clone(libc.so.6)
    2 read(libpthread.so.0),sock_read,BIO_read,ssl3_read_n,ssl3_get_record,ssl3_read_bytes,ssl3_read,SSL_read,vio_ssl_read(viossl.c:186),net_read_raw_loop(net_serv.cc:672),net_read_packet_header(net_serv.cc:756),net_read_packet(net_serv.cc:756),my_net_read(net_serv.cc:899),Protocol_classic::read_packet(protocol_classic.cc:808),Protocol_classic::get_command(protocol_classic.cc:965),do_command(sql_parse.cc:965),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)
    2 rand_bytes,tls1_enc,do_ssl3_write,ssl3_write_bytes,SSL_write,vio_ssl_write(viossl.c:225),net_write_raw_loop(net_serv.cc:500),net_write_packet(net_serv.cc:500),net_flush(net_serv.cc:222),net_send_ok(protocol_classic.cc:369),Protocol_classic::send_eof(protocol_classic.cc:668),THD::send_statement_status(sql_class.cc:4714),dispatch_command(sql_parse.cc:1925),do_command(sql_parse.cc:1023),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)
    2 pthread_rwlock_unlock(libpthread.so.0),CRYPTO_THREAD_unlock,rand_bytes,tls1_enc,do_ssl3_write,ssl3_write_bytes,SSL_write,vio_ssl_write(viossl.c:225),net_write_raw_loop(net_serv.cc:500),net_write_packet(net_serv.cc:500),net_flush(net_serv.cc:222),net_send_ok(protocol_classic.cc:369),Protocol_classic::send_eof(protocol_classic.cc:668),THD::send_statement_status(sql_class.cc:4714),dispatch_command(sql_parse.cc:1925),do_command(sql_parse.cc:1023),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)
    1 write(libpthread.so.0),sock_write,BIO_write,ssl3_write_pending,do_ssl3_write,ssl3_write_bytes,SSL_write,vio_ssl_write(viossl.c:225),net_write_raw_loop(net_serv.cc:500),net_write_packet(net_serv.cc:500),net_flush(net_serv.cc:222),net_send_ok(protocol_classic.cc:369),Protocol_classic::send_eof(protocol_classic.cc:668),THD::send_statement_status(sql_class.cc:4714),dispatch_command(sql_parse.cc:1925),do_command(sql_parse.cc:1023),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)

此时大部分线程都在读写过程中,perf数据:

可见之前的瓶颈已经降低很多了。测试得到oltp_point_select的TPS为336229.14,性能下降30.95%,与yaSSL的性能下降值26.03%相比略高。下表是短连接测试数据:

不启用SSL大约为用OpenSSL库启用SSL每秒访问数的4.5倍,而yaSSL这个数字则为7.6倍,显然OpenSSL的性能在这种场景下比yaSSL有很大提高。

2 透明加密测试组

下表为透明加密测试数据:

总体看,启用yaSSL透明加密时TPS都会下降。oltp_delete、oltp_insert、oltp_update_index、oltp_update_non_index、oltp_write_only场景比不加密情况性能大约低40%,oltp_point_select、oltp_read_only场景比不加密情况性能大约低20%。其中oltp_read_write场景、select_random_points场、select_random_ranges场景与bulk_insert场景加密与不加密相比差距不大。需要具体分析原因。

首先查看oltp_read_write场景的CPU利用率和IO情况,如下图:

从CPU利用率看,加密比不加密使用率有大幅提高,但依然没到100%。从IO看两者速度虽有差异,但利用率都接近100%,IO应该处于压满状态,变化不大。执行命令pt-pmp -p得到数据:

代码语言:javascript
复制
    Tue Jul  3 12:48:48 CST 2018
    7 __io_getevents_0_4,LinuxAIOHandler::collect(os0file.cc:2500),LinuxAIOHandler::poll(os0file.cc:2646),os_aio_linux_handler(os0file.cc:2702),os_aio_handler(os0file.cc:2702),fil_aio_wait(fil0fil.cc:5906),io_handler_thread(srv0start.cc:311),start_thread(libpthread.so.0),clone(libc.so.6)
    6 pthread_cond_wait,native_cond_wait(thr_cond.h:140),my_cond_wait(thr_cond.h:140),inline_mysql_cond_wait(thr_cond.h:140),Stage_manager::enroll_for(thr_cond.h:140),MYSQL_BIN_LOG::change_stage(binlog.cc:8655),MYSQL_BIN_LOG::ordered_commit(binlog.cc:9056),MYSQL_BIN_LOG::commit(binlog.cc:8330),ha_commit_trans(handler.cc:1795),trans_commit(transaction.cc:239),mysql_execute_command(sql_parse.cc:4354),Prepared_statement::execute(sql_prepare.cc:3935),Prepared_statement::execute_loop(sql_prepare.cc:3543),mysqld_stmt_execute(sql_prepare.cc:2549),dispatch_command(sql_parse.cc:1437),do_command(sql_parse.cc:1023),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)
    5 pthread_cond_wait,native_cond_wait(thr_cond.h:140),my_cond_wait(thr_cond.h:140),inline_mysql_cond_wait(thr_cond.h:140),Stage_manager::enroll_for(thr_cond.h:140),MYSQL_BIN_LOG::change_stage(binlog.cc:8655),MYSQL_BIN_LOG::ordered_commit(binlog.cc:9125),MYSQL_BIN_LOG::commit(binlog.cc:8330),ha_commit_trans(handler.cc:1795),trans_commit(transaction.cc:239),mysql_execute_command(sql_parse.cc:4354),Prepared_statement::execute(sql_prepare.cc:3935),Prepared_statement::execute_loop(sql_prepare.cc:3543),mysqld_stmt_execute(sql_prepare.cc:2549),dispatch_command(sql_parse.cc:1437),do_command(sql_parse.cc:1023),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)
    4 pthread_cond_wait,wait(os0event.cc:165),wait_low(os0event.cc:165),os_event_wait_low(os0event.cc:165),sync_array_wait_event(sync0arr.cc:475),wait(ut0mutex.ic:89),spin_and_try_lock(ut0mutex.ic:89),enter(ut0mutex.ic:89),enter(ut0mutex.ic:89),buf_LRU_buf_pool_running_out(ut0mutex.ic:89),row_ins_sec_index_entry_low(row0ins.cc:3168),row_ins_sec_index_entry(row0ins.cc:3420),row_ins_index_entry(row0ins.cc:3451),row_ins_index_entry_step(row0ins.cc:3451),row_ins(row0ins.cc:3451),row_ins_step(row0ins.cc:3451),row_insert_for_mysql_using_ins_graph(row0mysql.cc:1749),row_insert_for_mysql(row0mysql.cc:1873),ha_innobase::write_row(ha_innodb.cc:7630),handler::ha_write_row(handler.cc:7976),write_record(sql_insert.cc:1871),Sql_cmd_insert::mysql_insert(sql_insert.cc:769),Sql_cmd_insert::execute(sql_insert.cc:3103),mysql_execute_command(sql_parse.cc:4945),Prepared_statement::execute(sql_prepare.cc:3935),Prepared_statement::execute_loop(sql_prepare.cc:3543),mysqld_stmt_execute(sql_prepare.cc:2549),dispatch_command(sql_parse.cc:1437),do_command(sql_parse.cc:1023),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)
    3 pthread_cond_wait,wait(os0event.cc:165),wait_low(os0event.cc:165),os_event_wait_low(os0event.cc:165),sync_array_wait_event(sync0arr.cc:475),TTASEventMutex::wait(ut0mutex.ic:89),spin_and_try_lock(ib0mutex.h:850),enter(ib0mutex.h:850),PolicyMutex<TTASEventMutex<GenericPolicy>(ib0mutex.h:850),buf_page_io_complete(buf0buf.cc:5831),fil_aio_wait(fil0fil.cc:5940),io_handler_thread(srv0start.cc:311),start_thread(libpthread.so.0),clone(libc.so.6)

显然瓶颈在提交binlog上,将binglog日志关闭(注释掉log-bin),重启mysqld测试发现TPS提升约10%。再执行pt-pmp -p察看数据,此时瓶颈在执行读写操作时涉及到的insert buffer页面锁。设置innodb_change_buffering=none,关闭此功能,重启mysqld再次执行发现性能下降25%左右。此时发现瓶颈都是IO了。总体来看这个场景瓶颈在于IO,不加密状态CPU本身使用率并不高,加密后只是将CPU利用率提高了,并没有改变瓶颈,所以加密状态的TPS变化不大。

其次分析select_random_points场景的CPU利用率和IO情况,如下图:

从IO可以看出,主要执行过程中基本没有IO进行,怀疑操作过程中可能一直使用的buffer中的数据,在执行过程中使用命令查看buffer命中情况:

代码语言:javascript
复制
$ mysql> show engine innobase status;

查看到具体信息:

代码语言:javascript
复制
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 8795455488
Dictionary memory allocated 315349
Buffer pool size   524224
Free buffers       2969
Database pages     515364
Old database pages 190077
Modified db pages  0
Pending reads      0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 5433583, not young 935378889
0.00 youngs/s, 0.00 non-youngs/s
Pages read 70941635, created 32975923, written 55885804
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 515364, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]

确认了该场景使用的buffer数据,没有进行IO读取。CPU使用率基本没有变化,一直是压满了。根据透明加密设计原理,这个场景不会有加解密的操作。总体上应该不会对TPS有影响。

select_random_ranges这个场景与select_random_points的情况一样,总体上应该不会对TPS有影响。

bulk_insert这个场景的CPU利用率和IO情况,如下图:

这个场景CPU是压满的,io在加密和不加密都基本一样,也是满负荷了。察看perf数据:

执行pt-pmp -p命令数据如下:

代码语言:javascript
复制
    Mon Jul  2 17:33:00 CST 2018
    17 ut_delay(libc.so.6),rw_lock_x_lock_func(sync0rw.cc:751),pfs_rw_lock_x_lock_func(sync0rw.ic:705),btr_search_x_lock(sync0rw.ic:705),btr_search_update_hash_on_insert(sync0rw.ic:705),btr_cur_optimistic_insert(btr0cur.cc:3272),row_ins_clust_index_entry_low(row0ins.cc:2604),row_ins_clust_index_entry(row0ins.cc:3319),row_ins_index_entry(row0ins.cc:3449),row_ins_index_entry_step(row0ins.cc:3449),row_ins(row0ins.cc:3449),row_ins_step(row0ins.cc:3449),row_insert_for_mysql_using_ins_graph(row0mysql.cc:1749),row_insert_for_mysql(row0mysql.cc:1873),ha_innobase::write_row(ha_innodb.cc:7630),handler::ha_write_row(handler.cc:7976),write_record(sql_insert.cc:1871),Sql_cmd_insert::mysql_insert(sql_insert.cc:769),Sql_cmd_insert::execute(sql_insert.cc:3103),mysql_execute_command(sql_parse.cc:4945),mysql_parse(sql_parse.cc:5740),dispatch_command(sql_parse.cc:1503),do_command(sql_parse.cc:1023),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)
    10 __io_getevents_0_4,LinuxAIOHandler::collect(os0file.cc:2500),LinuxAIOHandler::poll(os0file.cc:2646),os_aio_linux_handler(os0file.cc:2702),os_aio_handler(os0file.cc:2702),fil_aio_wait(fil0fil.cc:5906),io_handler_thread(srv0start.cc:311),start_thread(libpthread.so.0),clone(libc.so.6)
    7 ut_delay(libc.so.6),rw_lock_x_lock_func(sync0rw.cc:751),pfs_rw_lock_x_lock_func(sync0rw.ic:705),btr_search_x_lock(sync0rw.ic:705),btr_search_update_hash_node_on_insert(sync0rw.ic:705),btr_cur_optimistic_insert(btr0cur.cc:3270),row_ins_clust_index_entry_low(row0ins.cc:2604),row_ins_clust_index_entry(row0ins.cc:3319),row_ins_index_entry(row0ins.cc:3449),row_ins_index_entry_step(row0ins.cc:3449),row_ins(row0ins.cc:3449),row_ins_step(row0ins.cc:3449),row_insert_for_mysql_using_ins_graph(row0mysql.cc:1749),row_insert_for_mysql(row0mysql.cc:1873),ha_innobase::write_row(ha_innodb.cc:7630),handler::ha_write_row(handler.cc:7976),write_record(sql_insert.cc:1871),Sql_cmd_insert::mysql_insert(sql_insert.cc:769),Sql_cmd_insert::execute(sql_insert.cc:3103),mysql_execute_command(sql_parse.cc:4945),mysql_parse(sql_parse.cc:5740),dispatch_command(sql_parse.cc:1503),do_command(sql_parse.cc:1023),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)
    5 pthread_cond_wait,wait(os0event.cc:165),wait_low(os0event.cc:165),os_event_wait_low(os0event.cc:165),sync_array_wait_event(sync0arr.cc:475),rw_lock_x_lock_func(sync0rw.cc:795),pfs_rw_lock_x_lock_func(sync0rw.ic:705),btr_search_x_lock(sync0rw.ic:705),btr_search_update_hash_on_insert(sync0rw.ic:705),btr_cur_optimistic_insert(btr0cur.cc:3272),row_ins_clust_index_entry_low(row0ins.cc:2604),row_ins_clust_index_entry(row0ins.cc:3319),row_ins_index_entry(row0ins.cc:3449),row_ins_index_entry_step(row0ins.cc:3449),row_ins(row0ins.cc:3449),row_ins_step(row0ins.cc:3449),row_insert_for_mysql_using_ins_graph(row0mysql.cc:1749),row_insert_for_mysql(row0mysql.cc:1873),ha_innobase::write_row(ha_innodb.cc:7630),handler::ha_write_row(handler.cc:7976),write_record(sql_insert.cc:1871),Sql_cmd_insert::mysql_insert(sql_insert.cc:769),Sql_cmd_insert::execute(sql_insert.cc:3103),mysql_execute_command(sql_parse.cc:4945),mysql_parse(sql_parse.cc:5740),dispatch_command(sql_parse.cc:1503),do_command(sql_parse.cc:1023),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)
    5 pthread_cond_wait,wait(os0event.cc:165),wait_low(os0event.cc:165),os_event_wait_low(os0event.cc:165),sync_array_wait_event(sync0arr.cc:475),rw_lock_x_lock_func(sync0rw.cc:795),pfs_rw_lock_x_lock_func(sync0rw.ic:705),btr_search_x_lock(sync0rw.ic:705),btr_search_update_hash_node_on_insert(sync0rw.ic:705),btr_cur_optimistic_insert(btr0cur.cc:3270),row_ins_clust_index_entry_low(row0ins.cc:2604),row_ins_clust_index_entry(row0ins.cc:3319),row_ins_index_entry(row0ins.cc:3449),row_ins_index_entry_step(row0ins.cc:3449),row_ins(row0ins.cc:3449),row_ins_step(row0ins.cc:3449),row_insert_for_mysql_using_ins_graph(row0mysql.cc:1749),row_insert_for_mysql(row0mysql.cc:1873),ha_innobase::write_row(ha_innodb.cc:7630),handler::ha_write_row(handler.cc:7976),write_record(sql_insert.cc:1871),Sql_cmd_insert::mysql_insert(sql_insert.cc:769),Sql_cmd_insert::execute(sql_insert.cc:3103),mysql_execute_command(sql_parse.cc:4945),mysql_parse(sql_parse.cc:5740),dispatch_command(sql_parse.cc:1503),do_command(sql_parse.cc:1023),handle_connection(connection_handler_per_thread.cc:309),pfs_spawn_thread(pfs.cc:2188),start_thread(libpthread.so.0),clone(libc.so.6)

发现场景的瓶颈主要是在锁上。这个锁是innodb的一个功能Adaptive Hash Index。关闭innodb_adaptive_hash_index参数或者设置innodb_adaptive_hash_index_parts=64,测试可以发现TPS增长到685541.92。此时可以发现瓶颈为将小事务日志写入重做日志缓冲区时的加锁(log_sys->mutex)过程。加密过程引起的降低不是主要瓶颈,所以最后表现为加密和不加密在这个场景的TPS变化不大。

对比OpenSSL与yaSSL的情况,总体上OpenSSL相对yaSSL来说都有较大幅度的性能提升。oltp_delete、oltp_insert、oltp_update_index、oltp_update_non_index、oltp_write_only场景OpenSSL加密相比yaSSL加密性能大约能提升40%,oltp_point_select、oltp_read_only、oltp_read_write场景OpenSSl加密相比yaSSL大约能提升20%性能,其他场景则差别不大。

select_random_points、select_random_ranges、bulk_insert场景已分析过,使用OpenSSL或者yaSSL都跟不使用加密TPS相差不大;oltp_read_write场景之前分析的瓶颈主要是在binlog、insert buffer页面锁以及io上,加解密应该影响不大,但数据显示使用OpenSSL加密的性能明显比使用yaSSL以及不使用加密的情况高,需要再分析下。

通过pt-pmp工具输出堆栈,可以确认两者在堆栈上没有明显区别,基本上都在读取数据页面。查看perf数据,不加密情况:

OpenSSL加密情况:

显然,OpenSSL加密情况下,降低了锁冲突,最后性能反而有所提升。

总结

总体上看SSL加密会导致性能损失,使用yaSSL库会导致性能有较大下降,而使用OpenSSL库性能下降幅度远低于yaSSL,与不使用SSL的性能差别不大,同时使用OpenSSL 1.1版本的库又比使用OpenSSL 1.0版本的库性能要高一些。

在SSL连接测试组中,大部分场景中,配置yaSSL或OpenSSL进行SSL连接与不配置SSL的性能在TPS表现差别不大;在部分测试场景(oltp_point_select、oltp_read_only、oltp_read_write、短连接)中,配置yaSSL或OpenSSL进行SSL连接性能下降较大。大多数情况(oltp_read_only、oltp_read_write、短连接)OpenSSL优于yaSSL;oltp_point_select场景下OpenSSL1.0版本性能明显低于yaSSL,但OpenSSL1.0版本性能与yaSSL相差不大。

在透明加密测试组中,大部分场景(oltp_delete、oltp_insert、oltp_update_index、oltp_update_non_index、oltp_write_only)配置yaSSL加密比不加密情况性能大约低40%,oltp_point_select、oltp_read_only场景yaSSL加密比不加密情况性能大约低20%;少部分场景(oltp_read_write、select_random_points、select_random_ranges、bulk_insert)yaSSL加密与不加密相比差距不大;配置OpenSSL加密比不加密情况总体差别不大,甚至还略有上升,尤其是oltp_read_write场景;总体上看配置OpenSSL加密比配置yaSSL加密性能有大幅提升。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-11-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯数据库技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 摘要
    • 测试内容
      • 测试环境
        • 1 SSL连接测试组
      • 1 SSL连接测试组测试步骤
        • 2 透明加密测试组
      • 测试结果及分析
        • 1 SSL连接测试组
        • 2 透明加密测试组
      • 总结
      相关产品与服务
      云服务器
      云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档