The limitation when getting blob data from oracle

寵の児 提交于 2019-12-13 19:19:11

问题


I am trying the download the BLOB data from oracle with JDBC . In order to know the average response time of getting the blob data, I am using JMeter to call the Getting blob data Java program with one or multiply threads.But I got the strange response time I could not understand.

I tried some tests below.(the blob data size is 1M)

1.Getting blob data with Jmeter in one thread

2.Getting blob data with Jmeter in two thread

3.Getting different blob data in the same table with JMeter in two thread

4.Getting different blob data in different tables with Jmeter in two thread.

.From the test 1 and 2,I found the response time of test 2 is almost twice of test 1 I can not understand this(My server has four cores and nobody is using that). I doubt that there is a lock when I get the same blob data so I tried the test 3. But the response time is almost the same as test2.And then I tried the test 4 to make sure whether there is a lock when I access the same table,but the response time of test 4 is also the same as the test3.

I think oracle can make deal with a lot the users' request at the same time,so I cannot understand the result I got from my tests. Does oracle have some limitation when getting the blob data at the same time?

here is the code for getting the blob data

    public SampleResult runTest(JavaSamplerContext arg0) {
              ////
    try {

        Class.forName(JDBC_CLASS_NAME);
        conn=DriverManager.getConnection(JDBC_THIN+dbserverIp+":"+port+":"+sid,dbuser,userPwd);
        statement=conn.createStatement();
        rs=statement.executeQuery(sqlText);
        responseStr=RESPONSE_DATA_OK_HEAD+KAIGYOU_CODE;
        if(rs.next()){
            String fileId=rs.getString(FILE_ID_COLUMN_NAME);
            oracle.sql.BLOB blob=((OracleResultSet)rs).getBLOB(BLOB_COLUMN_NAME);
            in=blob.getBinaryStream();

            int size=blob.getBufferSize();
            byte[] buffer=new byte[size];
            int len=-1;
            bos=new ByteArrayOutputStream();
            while((len=in.read(buffer))!=-1){
                readCount=readCount+1;
                bos.write(buffer,0,len);
            }
            byte[] blobValues=bos.toByteArray();
            responseStr=responseStr+fileId+","+blobValues.length+","+readCount+KAIGYOU_CODE;

        }else{
            responseStr=RESPONSE_DATA_ZERO;
        }
    } catch (Exception e) {
        e.printStackTrace();
        getNGSampleResult(e,sr);
        return sr;
    }finally{
        try {
            if(rs!=null){
                rs.close();
                rs=null;
            }
            if(statement!=null){
                statement.close();
                statement=null;
            }
            if(conn!=null){
                conn.close();
                conn=null;
            }
            if(in!=null){
                in.close();
                in=null;
            }
            if(bos!=null){
                bos.close();
                bos=null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            getNGSampleResult(e,sr);
            return sr;
        }
    }
    sr.sampleEnd();
    sr.setSuccessful(true);
    sr.setResponseCodeOK();
    sr.setResponseMessageOK();
    sr.setResponseData(responseStr,"UTF-8");
    sr.setDataType(SampleResult.TEXT);
    return sr;
}

here is the test plan

<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="2.1">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan"    enabled="true">
  <stringProp name="TestPlan.comments"></stringProp>
  <boolProp name="TestPlan.functional_mode">false</boolProp>
  <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
  <elementProp name="TestPlan.user_defined_variables" elementType="Arguments"  guiclass="ArgumentsPanel" testclass="Arguments" testname="User Parameter" enabled="true">
    <collectionProp name="Arguments.arguments">
      <elementProp name="env_test_date" elementType="Argument">
        <stringProp name="Argument.name">env_test_date</stringProp>
        <stringProp name="Argument.value">20130202</stringProp>
        <stringProp name="Argument.metadata">=</stringProp>
      </elementProp>
      <elementProp name="env_test_case" elementType="Argument">
        <stringProp name="Argument.name">env_test_case</stringProp>
        <stringProp name="Argument.value">Run at the same time</stringProp>
        <stringProp name="Argument.metadata">=</stringProp>
      </elementProp>
      <elementProp name="env_test_filesize" elementType="Argument">
        <stringProp name="Argument.name">env_test_filesize</stringProp>
        <stringProp name="Argument.value">1M</stringProp>
        <stringProp name="Argument.metadata">=</stringProp>
      </elementProp>
      <elementProp name="env_test_thread" elementType="Argument">
        <stringProp name="Argument.name">env_test_thread</stringProp>
        <stringProp name="Argument.value">2users</stringProp>
        <stringProp name="Argument.metadata">=</stringProp>
      </elementProp>
    </collectionProp>
  </elementProp>
  <stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
  <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="ULDLtest" enabled="true">
    <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
    <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="loop controller" enabled="true">
      <boolProp name="LoopController.continue_forever">false</boolProp>
      <intProp name="LoopController.loops">-1</intProp>
    </elementProp>
    <stringProp name="ThreadGroup.num_threads">2</stringProp>
    <stringProp name="ThreadGroup.ramp_time">1</stringProp>
    <longProp name="ThreadGroup.start_time">1358319600000</longProp>
    <longProp name="ThreadGroup.end_time">1358328499000</longProp>
    <boolProp name="ThreadGroup.scheduler">true</boolProp>
    <stringProp name="ThreadGroup.duration">300</stringProp>
    <stringProp name="ThreadGroup.delay"></stringProp>
  </ThreadGroup>
  <hashTree>
    <JavaSampler guiclass="JavaTestSamplerGui" testclass="JavaSampler" testname="Java DL BLOB Request" enabled="true">
      <elementProp name="arguments" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" enabled="true">
        <collectionProp name="Arguments.arguments">
          <elementProp name="SQL_TEXT" elementType="Argument">
            <stringProp name="Argument.name">SQL_TEXT</stringProp>
            <stringProp name="Argument.value">select * from t_download_file_data t where t.file_id=&apos;testdata1M.csv&apos;</stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
          </elementProp>
          <elementProp name="DB_USER" elementType="Argument">
            <stringProp name="Argument.name">DB_USER</stringProp>
            <stringProp name="Argument.value">xxxx</stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
          </elementProp>
          <elementProp name="USER_PWD" elementType="Argument">
            <stringProp name="Argument.name">USER_PWD</stringProp>
            <stringProp name="Argument.value">xxxx</stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
          </elementProp>
          <elementProp name="SID" elementType="Argument">
            <stringProp name="Argument.name">SID</stringProp>
            <stringProp name="Argument.value">xxxxx</stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
          </elementProp>
          <elementProp name="DBSERVER_IP" elementType="Argument">
            <stringProp name="Argument.name">DBSERVER_IP</stringProp>
            <stringProp name="Argument.value">xxx.xx.xx.xx</stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
          </elementProp>
          <elementProp name="PORT" elementType="Argument">
            <stringProp name="Argument.name">PORT</stringProp>
            <stringProp name="Argument.value">1521</stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
          </elementProp>
        </collectionProp>
      </elementProp>
      <stringProp name="classname">sample.TestSamplerClient</stringProp>
    </JavaSampler>
    <hashTree/>
    <ResultCollector guiclass="TableVisualizer" testclass="ResultCollector" testname="Reust for table" enabled="false">
      <boolProp name="ResultCollector.error_logging">false</boolProp>
      <objProp>
        <name>saveConfig</name>
        <value class="SampleSaveConfiguration">
          <time>true</time>
          <latency>true</latency>
          <timestamp>true</timestamp>
          <success>true</success>
          <label>true</label>
          <code>true</code>
          <message>true</message>
          <threadName>true</threadName>
          <dataType>true</dataType>
          <encoding>false</encoding>
          <assertions>true</assertions>
          <subresults>true</subresults>
          <responseData>false</responseData>
          <samplerData>false</samplerData>
          <xml>true</xml>
          <fieldNames>false</fieldNames>
          <responseHeaders>false</responseHeaders>
          <requestHeaders>false</requestHeaders>
          <responseDataOnError>false</responseDataOnError>
          <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
          <assertionsResultsToSave>0</assertionsResultsToSave>
          <bytes>true</bytes>
        </value>
      </objProp>
      <stringProp name="filename"></stringProp>
    </ResultCollector>
    <hashTree/>
    <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="Result for graph" enabled="false">
      <boolProp name="ResultCollector.error_logging">false</boolProp>
      <objProp>
        <name>saveConfig</name>
        <value class="SampleSaveConfiguration">
          <time>true</time>
          <latency>true</latency>
          <timestamp>true</timestamp>
          <success>true</success>
          <label>true</label>
          <code>true</code>
          <message>true</message>
          <threadName>true</threadName>
          <dataType>true</dataType>
          <encoding>false</encoding>
          <assertions>true</assertions>
          <subresults>true</subresults>
          <responseData>false</responseData>
          <samplerData>false</samplerData>
          <xml>true</xml>
          <fieldNames>false</fieldNames>
          <responseHeaders>false</responseHeaders>
          <requestHeaders>false</requestHeaders>
          <responseDataOnError>false</responseDataOnError>
          <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
          <assertionsResultsToSave>0</assertionsResultsToSave>
          <bytes>true</bytes>
        </value>
      </objProp>
      <stringProp name="filename"></stringProp>
    </ResultCollector>
    <hashTree/>
    <ResultCollector guiclass="StatVisualizer" testclass="ResultCollector" testname="Report" enabled="true">
      <boolProp name="ResultCollector.error_logging">false</boolProp>
      <objProp>
        <name>saveConfig</name>
        <value class="SampleSaveConfiguration">
          <time>true</time>
          <latency>true</latency>
          <timestamp>true</timestamp>
          <success>true</success>
          <label>true</label>
          <code>true</code>
          <message>true</message>
          <threadName>true</threadName>
          <dataType>true</dataType>
          <encoding>false</encoding>
          <assertions>true</assertions>
          <subresults>true</subresults>
          <responseData>false</responseData>
          <samplerData>false</samplerData>
          <xml>true</xml>
          <fieldNames>false</fieldNames>
          <responseHeaders>false</responseHeaders>
          <requestHeaders>false</requestHeaders>
          <responseDataOnError>false</responseDataOnError>
          <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
          <assertionsResultsToSave>0</assertionsResultsToSave>
          <bytes>true</bytes>
        </value>
      </objProp>
      <stringProp name="filename">log\ULDLPerformance_${env_test_case}_${env_test_thread}_${env_test_filesize}_${env_test_date}.jtl</stringProp>
    </ResultCollector>
    <hashTree/>
  </hashTree>
   </hashTree>
  </hashTree>
  </jmeterTestPlan>

回答1:


As you coded it You are measuring : - connection to db - blob read - connection close

You could maybe use JDBC Configuration element:

http://jmeter.apache.org/usermanual/component_reference.html#JDBC_Connection_Configuration

So that connection are established before you sample.

Then modify your code by looking at how jdbc request works to get access to DB connection:

 conn = DataSourceElement.getConnection("Variable Name used in JDBC_Connection_Configuration");



回答2:


Oracle databases can scale to hundreds of thousands of simultaneous users, given sufficient hardware. So the result you're seeing is either due to limitations of your hardware or a flaw in teh way you're written your program.

For instance, if your server has a single core then it can only do one thing at a time. So, two users running against it would take twice as long. Not saying that is what is actually happening, just illustrating the kind of thing it could be.



来源:https://stackoverflow.com/questions/14766722/the-limitation-when-getting-blob-data-from-oracle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!