153 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			153 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
Execution Profiles (experimental)
 | 
						|
=================================
 | 
						|
 | 
						|
Execution profiles are an experimental API aimed at making it easier to execute requests in different ways within
 | 
						|
a single connected ``Session``. Execution profiles are being introduced to deal with the exploding number of
 | 
						|
configuration options, especially as the database platform evolves more complex workloads.
 | 
						|
 | 
						|
The Execution Profile API is being introduced now, in an experimental capacity, in order to take advantage of it in
 | 
						|
existing projects, and to gauge interest and feedback in the community. For now, the legacy configuration remains
 | 
						|
intact, but legacy and Execution Profile APIs cannot be used simultaneously on the same client ``Cluster``.
 | 
						|
 | 
						|
This document explains how Execution Profiles relate to existing settings, and shows how to use the new profiles for
 | 
						|
request execution.
 | 
						|
 | 
						|
Mapping Legacy Parameters to Profiles
 | 
						|
-------------------------------------
 | 
						|
 | 
						|
Execution profiles can inherit from :class:`.cluster.ExecutionProfile`, and currently provide the following options,
 | 
						|
previously input from the noted attributes:
 | 
						|
 | 
						|
- load_balancing_policy - :attr:`.Cluster.load_balancing_policy`
 | 
						|
- request_timeout - :attr:`.Session.default_timeout`, optional :meth:`.Session.execute` parameter
 | 
						|
- retry_policy - :attr:`.Cluster.default_retry_policy`, optional :attr:`.Statement.retry_policy` attribute
 | 
						|
- consistency_level - :attr:`.Session.default_consistency_level`, optional :attr:`.Statement.consistency_level` attribute
 | 
						|
- serial_consistency_level - :attr:`.Session.default_serial_consistency_level`, optional :attr:`.Statement.serial_consistency_level` attribute
 | 
						|
- row_factory - :attr:`.Session.row_factory` attribute
 | 
						|
 | 
						|
When using the new API, these parameters can be defined by instances of :class:`.cluster.ExecutionProfile`.
 | 
						|
 | 
						|
Using Execution Profiles
 | 
						|
------------------------
 | 
						|
Default
 | 
						|
~~~~~~~
 | 
						|
 | 
						|
.. code:: python
 | 
						|
 | 
						|
    from cassandra.cluster import Cluster
 | 
						|
    cluster = Cluster()
 | 
						|
    session = cluster.connect()
 | 
						|
    local_query = 'SELECT rpc_address FROM system.local'
 | 
						|
    for _ in cluster.metadata.all_hosts():
 | 
						|
        print session.execute(local_query)[0]
 | 
						|
 | 
						|
 | 
						|
.. parsed-literal::
 | 
						|
 | 
						|
    Row(rpc_address='127.0.0.2')
 | 
						|
    Row(rpc_address='127.0.0.1')
 | 
						|
 | 
						|
 | 
						|
The default execution profile is built from Cluster parameters and default Session attributes. This profile matches existing default
 | 
						|
parameters.
 | 
						|
 | 
						|
Initializing cluster with profiles
 | 
						|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
						|
 | 
						|
.. code:: python
 | 
						|
 | 
						|
    from cassandra.cluster import ExecutionProfile
 | 
						|
    from cassandra.policies import WhiteListRoundRobinPolicy
 | 
						|
 | 
						|
    node1_profile = ExecutionProfile(load_balancing_policy=WhiteListRoundRobinPolicy(['127.0.0.1']))
 | 
						|
    node2_profile = ExecutionProfile(load_balancing_policy=WhiteListRoundRobinPolicy(['127.0.0.2']))
 | 
						|
 | 
						|
    profiles = {'node1': node1_profile, 'node2': node2_profile}
 | 
						|
    session = Cluster(execution_profiles=profiles).connect()
 | 
						|
    for _ in cluster.metadata.all_hosts():
 | 
						|
        print session.execute(local_query, execution_profile='node1')[0]
 | 
						|
 | 
						|
 | 
						|
.. parsed-literal::
 | 
						|
 | 
						|
    Row(rpc_address='127.0.0.1')
 | 
						|
    Row(rpc_address='127.0.0.1')
 | 
						|
 | 
						|
 | 
						|
.. code:: python
 | 
						|
 | 
						|
    for _ in cluster.metadata.all_hosts():
 | 
						|
        print session.execute(local_query, execution_profile='node2')[0]
 | 
						|
 | 
						|
 | 
						|
.. parsed-literal::
 | 
						|
 | 
						|
    Row(rpc_address='127.0.0.2')
 | 
						|
    Row(rpc_address='127.0.0.2')
 | 
						|
 | 
						|
 | 
						|
.. code:: python
 | 
						|
 | 
						|
    for _ in cluster.metadata.all_hosts():
 | 
						|
        print session.execute(local_query)[0]
 | 
						|
 | 
						|
 | 
						|
.. parsed-literal::
 | 
						|
 | 
						|
    Row(rpc_address='127.0.0.2')
 | 
						|
    Row(rpc_address='127.0.0.1')
 | 
						|
 | 
						|
Note that, even when custom profiles are injected, the default ``TokenAwarePolicy(DCAwareRoundRobinPolicy())`` is still
 | 
						|
present. To override the default, specify a policy with the :data:`~.cluster.EXEC_PROFILE_DEFAULT` key.
 | 
						|
 | 
						|
.. code:: python
 | 
						|
 | 
						|
    from cassandra.cluster import EXEC_PROFILE_DEFAULT
 | 
						|
    profile = ExecutionProfile(request_timeout=30)
 | 
						|
    cluster = Cluster(execution_profiles={EXEC_PROFILE_DEFAULT: profile})
 | 
						|
 | 
						|
 | 
						|
Adding named profiles
 | 
						|
~~~~~~~~~~~~~~~~~~~~~
 | 
						|
 | 
						|
New profiles can be added constructing from scratch, or deriving from default:
 | 
						|
 | 
						|
.. code:: python
 | 
						|
 | 
						|
    locked_execution = ExecutionProfile(load_balancing_policy=WhiteListRoundRobinPolicy(['127.0.0.1']))
 | 
						|
    node1_profile = 'node1_whitelist'
 | 
						|
    cluster.add_execution_profile(node1_profile, locked_execution)
 | 
						|
    
 | 
						|
    for _ in cluster.metadata.all_hosts():
 | 
						|
        print session.execute(local_query, execution_profile=node1_profile)[0]
 | 
						|
 | 
						|
 | 
						|
.. parsed-literal::
 | 
						|
 | 
						|
    Row(rpc_address='127.0.0.1')
 | 
						|
    Row(rpc_address='127.0.0.1')
 | 
						|
 | 
						|
See :meth:`.Cluster.add_execution_profile` for details and optional parameters.
 | 
						|
 | 
						|
Passing a profile instance without mapping
 | 
						|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
						|
 | 
						|
We also have the ability to pass profile instances to be used for execution, but not added to the mapping:
 | 
						|
 | 
						|
.. code:: python
 | 
						|
 | 
						|
    from cassandra.query import tuple_factory
 | 
						|
    
 | 
						|
    tmp = session.execution_profile_clone_update('node1', request_timeout=100, row_factory=tuple_factory)
 | 
						|
 | 
						|
    print session.execute(local_query, execution_profile=tmp)[0]
 | 
						|
    print session.execute(local_query, execution_profile='node1')[0]
 | 
						|
 | 
						|
.. parsed-literal::
 | 
						|
 | 
						|
    ('127.0.0.1',)
 | 
						|
    Row(rpc_address='127.0.0.1')
 | 
						|
 | 
						|
The new profile is a shallow copy, so the ``tmp`` profile shares a load balancing policy with one managed by the cluster.
 | 
						|
If reference objects are to be updated in the clone, one would typically set those attributes to a new instance.
 |