Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
OptimizingthePerformanceandScalabilityofJavaApplicationsThatUseanRDBMSTIP4068
Kuassi Mensah,Director,ProductManagementJeanDeLavarene,Director,DevelopmentNirmalaSundarappa,PrincipalProductManagerOracleOctober25,2018
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
SafeHarborStatement
Thefollowingisintendedtooutlineourgeneralproductdirection.Itisintendedforinformationpurposesonly,andmaynotbeincorporatedintoanycontract.Itisnotacommitmenttodeliveranymaterial,code,orfunctionality,andshouldnotberelieduponinmakingpurchasingdecisions.Thedevelopment,release,timing, andpricingofanyfeaturesorfunctionalitydescribedforOracle’sproductsmaychangeandremainsatthesolediscretionofOracleCorporation.
Confidential– OracleInternal/Restricted/HighlyRestricted
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
ProgramAgenda
SpeedingupDatabaseOperations
ScalingOutJavaWorkloads
Q&A
Thecontentisbasedonmyblogpost@https://bit.ly/2EKl8b6
1
2
3
Confidential– OracleInternal/Restricted/HighlyRestricted 4
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
ProgramAgenda
SpeedingupDatabaseOperations
ScalingOutJavaWorkloads
Q&A
1
2
3
Confidential– OracleInternal/Restricted/HighlyRestricted 5
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
SpeedingupDatabaseConnectivity
• Client-sideconnectionpools– Standalone:UCP,DBCP,C3P0– JavaContainers:Tomcat,Weblogic,JBoss,andsoon
• Server-sideconnectionpools:DRCP,SharedServers.• Proxyconnectionpools– CMAN-TDM(morelater)–MySQLRouter– NGINX– andsoon
Confidential– OracleInternal/Restricted/HighlyRestricted 6
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
SpeedingupDatabaseConnectivityOtherOptimizations
• DeferringConnectionHealthCheckPoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();pds.setSecondsToTrustIdleConnection(30);
• De-Prioritizationoffailednodes– assumeDBnodesA,B&C• Aisdown,it’llbede-prioritizebyJDBCforthenext10min• JavaconnectionsareallocatedfromB&C.• After10minutes,thede-prioritizationofAends,connectionsareallocatedfromA,B,&C.oracle.net.SQLNET.DOWN_HOSTS_TIMEOUT
Confidential– OracleInternal/Restricted/HighlyRestricted 7
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
SpeedingupSQLStatementsProcessing
• PreparedStatements– Parseonce,re-executeatwill;avoidshard-parsesandpreventsSQLinjection
• StatementsCaching(implicit)– enabledonthedatasource objectOracleDataSource ods = new OracleDataSource(); ods.setConnectionCachingEnabled( true ); ods.setImplicitCachingEnabled(true); ...cacheProps.put( "MaxStatementsLimit", "50" );
– orontheconnectionobject((OracleConnection)conn).setStatementCacheSize(10);
Confidential– OracleInternal/Restricted/HighlyRestricted 8
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
SpeedingupSQLStatementsProcessingArrayFetch,ArrayDML
• ArrayFetchstmt.setFetchSize(20);
– Hardlimit:SDUsize2MBDB12candup,64KBwithDB11.2,32Kpre-11.2
• ArrayDMLPreparedStatement pstmt = conn.prepareStatement("INSERT INTO employees VALUES(?, ?)");
pstmt.setInt(1, 2000);pstmt.setString(2, "Milo Mumford");pstmt.addBatch();pstmt.setInt(1, 3000);pstmt.setString(2, "Sulu Simpson");pstmt.addBatch();int[] updateCounts = pstmt.executeBatch();...
Confidential– OracleInternal/Restricted/HighlyRestricted 9
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
ResultSets CachingwithChangeNotification
1. EnableServer-sideResultSet caching(RDBMS&Client)2. Grant“change notification”totheschema3. Createaregistration
DatabaseChangeRegistration dcr = conn.registerDatabaseChangeNotifictaion(prop);
4. Associateaquerywiththeregistration((OracleStatement)stmt).setDatabaseChangeRegistration(dcr);
5. ListentothenotificationDCNListener list = new DCNListener(); dcr.addListener(list);
Confidential– OracleInternal/Restricted/HighlyRestricted
TheHardWay
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
ResultSets CachingwithChangeNotification
1. EnableServer-side&Client-sideResultSet cachingCLIENT_RESULT_CACHE_SIZE=100M // maximum cache size, in bytesCLIENT_RESULT_CACHE_LAG=1000 //max delay for refreshing the cache(ms)
2. Setoracle.jdbc.enableQueryResultCache totrue
3. Add/*+ RESULT_CACHE */ tothequeryoruseTableAnnotation
SELECT /*+ RESULT_CACHE */ product_name, unit_priceFROM PRODUCTS WHERE unit_price > 100
Confidential– OracleInternal/Restricted/HighlyRestricted
TheEasyWay
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
NetworkTrafficOptimization
• NetworkDataCompression// Enabling Network Compression in Java
prop.setProperty("oracle.net.networkCompression","on");
// Optional configuration for setting the client compression threshold.
prop.setProperty("oracle.net.networkCompressionThreshold","1024"); ds.setConnectionProperties(prop);
ds.setURL(url);
Connection conn = ds.getConnection();
• SessionMultiplexing– CMANfunnelsmultipledatabaseconnectionsoverasinglenetworkconnection• Seemoredetailsinthe NetServicesAdminGuide.https://bit.ly/2P7AEC1
Confidential– OracleInternal/Restricted/HighlyRestricted 12
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
In-PlaceProcessing
• Motivations– Cutthenetworktraffic
• How:movetheJavacodeclosetodata!– Hadoop,Spark,Flink– JavaStoredProceduresinRDBMSsession/process
• StoredProceduresareso70sbutefficient!– Newfashion:REST-wrappedstoredproceduresareagooddesignchoicefordata-boundmicroservices.
• JavainthedatabasecodesamplesonGitHubhttps://bit.ly/2PbUo7m
Confidential– OracleInternal/Restricted/HighlyRestricted 13
JDBC(internal)
SQL
SQLSQL
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
In-PlaceProcessingRESTfulMiroService forJSONProcessing
{"EmpId":"100","FirstName":"Kuassi","LastName":"Mensah","Job":"Manager","Email":"[email protected]","Address":{"City":"Redwood", "Country" :"US"}
}
JSON
http://localhost:8090/ords/ordstest/load/routes/nashorn/selectbyid/100
OracleRESTDataServices
Dbcall
URIRequestorHTTP(s) postmappedtoSQLrequest
JDBCConnection
Pool
OracleDatabase
URI http(s)
JSON
JavaMicroService
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
ProgramAgenda
SpeedingupDatabaseOperations
ScalingOutJavaWorkloads
Q&A
1
2
3
Confidential– OracleInternal/Restricted/HighlyRestricted 15
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
• Non-Scalableapproach
Confidential– OracleInternal/Restricted/HighlyRestricted
HorizontalScalingofJavaWorkload- Sharded Databases
UCP(50)
UCP(25)
UCP(25)
UCP(35)
UCP(40)
UCP(25)
PDB1 PDB2 PDB3 PDB4 PDB5 PDB6 PDB1 PDB2 PDB3 PDB4 PDB5 PDB6
SharedPool(50)
• Shared,consolidatedconnectionpool- Density,performance,scalability
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
SharedPoolforMultiTenant Databases
CDB
PDB1
PDB2
PDB3
PDB2Connections
PDB3Connections
PDB1Connections
GetconnectionforServiceonPDB-3
RepurposeConnectionforPDB3
UserborrowstherepurposedconnectionforPDB3
UCPasaSharedPool
NoconnectionavailableforPDB3
JavaSE9furnishesthe standardAPIs forbuildingthesharding andsuper-shardingkeys.DataSource ds = new MyDataSource(); // ShardingKeyshardingKey = ds.createShardingKeyBuilder() .subkey("abc", JDBCType.VARCHAR) .subkey(94002, JDBCType.INTEGER) .build();
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.| Confidential– OracleInternal/Restricted/HighlyRestricted
ProxyConnectionPools
Databaseproxiesthatsitbetweenthedatabaseclients(i.e.,Javaapps,Webtiers)andtheRDBMS
• MySQLRouter
• OracleDatabaseCMANinTrafficDirectorMode(CMAN-TDM)
• NGINXAllowthousandsofmid-tierstoshareacommonconnectionpool
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
• Fullytransparenttoapplications• ConnectionPoolingacrossapplicationservers
• TransparentConnect-timeandRun-timeloadbalancingofdatabaseconnections
• TransparentlyStatementCaching,Prefetchingandotherperformancefeatures
• Routesdatabasetraffictorightinstance• OffloadingofEncryptionfromDatabase
19
OracleConnectionManager- TrafficDirectorModeDatabaseProxy
19
C++
ConnectionManagerTrafficDirector
C
Databases
Confidential– OracleInternal
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.| Confidential– OracleInternal/Restricted/HighlyRestrictedOracleConfidential– HighlyRestricted
CMANinTrafficDirectorModeInstances
PDB12
CDB2
CDB1
PDB11
PDB23
PDB24
ONSServer
ResultsetCache
WorkerThreads
cmop process1……………………
cmop processn
m1m2
m3
11.2JDBC- Thin
TenantDBCloudApplications
12.2OCI
18cODP.NET
12.1cx_Oracle
12.1cx_OracleProxyResidentConnection Pool
HA&RLB
WorkerThreads
ResultsetCache
DedicatedOutboundConnections
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.| Confidential– OracleInternal 21
• Transparentlyenhanceperformance• Optimizefetchingofdataandtransparentlycachestatements/results
• Byleveragingexistingoraaccess.xmlparameters
<config_description><config_alias>svcname_config</config_alias><parameters>
<stmt_cache><size>50</size></stmt_cache><prefetch><rows>100</rows></prefetch> <result_cache>
<max_rset_rows>500</max_rset_rows><max_rset_size>75000</max_rset_size><max_size>135536</max_size>
</result_cache></parameters>
</config_description>
Performance
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
AsynchronousJavaDatabaseAccess(ADBA)
• AnewJavastandarddatabaseaccessAPIthatneverblocksuserthreads– AlternateAPItoJDBC;notareplacement,noreferencetojava.sql
• AsynchronousandReactiveappshavebetterthroughput• DevelopedbytheJDBCExpertGroupwithcommunityinput• BuiltexclusivelyontheJavaSEclasslibrary– Java8j.u.c.CompletionStage andj.u.c.CompletableFuture– Java9StreamsAPI(j.u.c.Flow)
• TargetedforanearfutureJavaSErelease
22
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
ADBA- DesignChoicesandStatus
• DesignChoices– Rigoroususeoftypes– Builderpattern– FluentAPI– Avoidcallbackhell
• Status– TheAPIisavailableonOpenJDKathttp://oracle.com/goto/java-async-db– [email protected]– PlaywithADBAoverJDBC
https://github.com/oracle/oracle-db-examples/tree/master/java/AoJ
23
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
TrivialInsertpublic void trivialInsert(DataSource ds) {String sql = "insert into tab values (:id, :name, :answer)";
try (Session session = ds.getSession()) { session.rowCountOperation(sql) .set("id", 1, AdbaType.NUMERIC)
} }
24
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
TrivialSelectpublic void trivialSelect(DataSource ds, List<Integer> result) { String sql = "select id, name, answer from tab where id = :target"; try (Session session = ds.getSession()) {
session.<List<Integer>>rowOperation(sql) .set("target", 42, AdbaType.NUMERIC)} } .collect(() -> result,
(list, row) -> list.add(row.at("answer").get(Integer.class)))
.submit(); }
}
25
Copyright©2018, Oracleand/oritsaffiliates.Allrightsreserved.|
ProgramAgenda
SpeedingupDatabaseOperations
ScalingOutJavaWorkloads
Q&A
1
2
3
Confidential– OracleInternal/Restricted/HighlyRestricted 26