<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>Hi, </div><div><br></div><div>I am doing some tests using SWIFT and S3 Python client API. Test is very simple I have multiple file (around 1GB ) in the SWIFT store and  I am accessing 64k data by specifying byte range. The result is a bit surprising and I couldn't really understand the reason. I need some hits to get the proper understanding.  </div><div><br></div><div>I am getting significantly low performance with SWIFT python client compare to S3 python Client. I am running 8 clients and with S3 API the successful download requests per second are 240 where as with SWIFT API the successful download requests per second are 157. Similarly </div><div><br></div><div>Client,  S3,  SWIFT</div><div>16, 490, 215</div><div>24, 709, 238</div><div><br></div><div>Each client sends a request to get 64k block. </div><div><br></div><div>Following is how I am using SWIFT python code. </div><div><br></div><div>To make things simple I am using port 80 and simple HTTP requests. </div><div><br></div><div>--------------------------------------------------------------------------------------------</div><div><div>from common.client import ClientException, get_auth, get_container, get_object, get_object_with_range, put_container, put_object, delete_container, delete_objec</div><div>t, head_object</div></div><div><br></div><div><div>def getAuth(self):</div><div>        return  get_auth(self.url, self.user, self.passwd)</div></div><div><br></div><div>def get(self, container, objectName, range, dataSize):</div><div><div>        try:    </div><div>            res = get_object_with_range(self.credentials[0], self.credentials[1], container, objectName, range, None, dataSize)</div><div>        except ClientException:</div><div>            res = 'no'</div><div>        return res</div></div><div><br></div><div><br></div><div><div>def get_object_with_range(url, token, container, name, range, http_conn=None,</div><div>               resp_chunk_size=None):</div><div><br></div><div>    """</div><div>    Get an object with the byte range</div><div><br></div><div>    :param url: storage URL</div><div>    :param token: auth token</div><div>    :param container: container name that the object is in</div><div>    :param name: object name to get</div><div>    :param range: object byte range for example "bytes=0-300" </div><div>    :param http_conn: HTTP connection object (If None, it will create the</div><div>                      conn object)</div><div>    :param resp_chunk_size: if defined, chunk size of data to read. NOTE: If</div><div>                            you specify a resp_chunk_size you must fully read</div><div>                            the object's contents before making another</div><div>                            request.</div><div>    :returns: a tuple of (response headers, the object's contents) The response</div><div>              headers will be a dict and all header names will be lowercase.</div><div>    :raises ClientException: HTTP GET request failed</div><div>    """</div><div>    if range == '':</div><div>        return 'valid range is required.'</div><div>    h = {}</div><div>    if http_conn:</div><div>        parsed, conn = http_conn</div><div>    else:</div><div>        parsed, conn = http_connection(url)</div><div>    path = '%s/%s/%s' % (parsed.path, quote(container), quote(name))</div><div>   <font class="Apple-style-span" color="#D70000"> h['X-Auth-Token'] = token</font></div><div><font class="Apple-style-span" color="#D70000">    h['Range'] = range</font></div><div>    #conn.request('GET', path, '', {'X-Auth-Token': token, 'Range':'bytes=0-400'})</div><div>    <font class="Apple-style-span" color="#D70000">conn.request('GET', path, '', h)</font></div><div>    resp = conn.getresponse()</div><div>    if resp.status < 200 or resp.status >= 300:</div><div>        resp.read()</div><div>        raise ClientException('Object GET failed', http_scheme=parsed.scheme,</div><div>                http_host=conn.host, http_port=conn.port, http_path=path,</div><div>                http_status=resp.status, http_reason=resp.reason)</div><div>    if resp_chunk_size:</div><div><br></div><div>        def _object_body():</div><div>            buf = resp.read(resp_chunk_size)</div><div>            while buf:</div><div>                yield buf</div><div>                buf = resp.read(resp_chunk_size)</div><div>        object_body = _object_body()</div><div>    else:</div><div>        object_body = resp.read()</div><div>    resp_headers = {}</div><div>    for header, value in resp.getheaders():</div><div>        resp_headers[header.lower()] = value</div><div>    return resp_headers, object_body</div></div><div><br></div><div><br></div><div><br></div><div>--------------------------------------------------------------------------------------------</div><div><br></div><div><br></div><div>Where </div><div>url= <a href="http://myserv.uu.se:80/auth/v1.0">http://myserv.uu.se:80/auth/v1.0</a></div><div>dataSize = 64000</div><div>range = 'bytes=1-64000'</div><div>getAuth return the URL and the token in credentials[0] and credentials[1].</div><div><br></div><div>method  get_object_with_range is exactly same as get_object except it handles the range tag as well in the header (highlighted in the red color). </div><div><br></div><div>And since its is simple http request so it shouldn't make much difference.</div><div><br></div><div>Before the test I was expecting that both of the clients should be similar or even Swift Client should have a bit better performance as in I am passing the url and the token to the get method. The result I am getting is strange to me. </div><div><br></div><div>Can someone please point out what I am doing wrong ?   </div><div><br></div><div>Thanks in advance.</div><div><br></div><div>Regards..</div><div>Salman.</div><div><div><br></div><br class="Apple-interchange-newline">
</div>
<br></body></html>