As a SAS Viya user, you may be wondering whether it is possible to execute data append and data update concurrently to a global Cloud Analytic Services (CAS) table from two or more CAS sessions. (Learn more about CAS.) How would this impact the report view while data append or data update is running on a global CAS table? These questions are even more important for those using the programming interface to load and update data in CAS. This post discusses data append, data update, and concurrency in CAS.
Two or more CAS sessions can simultaneously submit a data append and data update process to a CAS table, but only one process at a time can run against the same CAS table. The multiple append and update processes execute in serial, one after another, never running in a concurrent fashion. Whichever CAS session is first to acquire the write lock on a global CAS table prevails, appending or updating the data first. The other append and update processes must wait in a queue to acquire the write lock.
During the data append process, the appended data is not available to end users or reports until all rows are inserted and committed into the CAS table. While data append is running, users can still render reports against the CAS table using the original data, but excluding the appended rows.
Similarly, during the data update process, the updated data is not available to users or reports until the update process is complete. However, CAS lets you render reports using the original (non-updated) data, as the CAS table is always available for the read process. During the data update process, CAS makes additional copies into memory of the to-be-updated blocks containing rows in order to perform the update statement. Once the update process is complete, the additional and now obsolete copies of blocks, are removed from CAS. Data updates to a global CAS table is an expensive operation in terms of CPU and memory usage. You have to factor in the additional overhead memory or CAS_CACHE space to support the updates. The space requirement depends on the number of rows being affected by the update process.
At any given time, there could be only one active write process (append/update) against a global CAS table. However, there could be many concurrent active read processes against a global CAS table. A global CAS table is always available for read processes, even when an append or update process is running on the same CAS table.
The following log example describes two simultaneous CAS sessions executing data appends to a CAS table. Both append processes were submitted to CAS with a gap of a few seconds. Notice the execution time for the second CAS session MYSESSION1 is double the time that it took the first CAS session to append the same size of data to the CAS table. This shows that both appends were executing one after another. The amount of memory used and the CAS_CACHE location also shows that both processes were running one after another in a serial fashion.
Log from simultaneous CAS session MYSESSION submitting APPEND
58 proc casutil ; NOTE: The UUID '1411b6f2-e678-f546-b284-42b6907260e9' is connected using session MYSESSION. 59 load data=mydata.big_prdsale 60 outcaslib="caspath" casout="big_PRDSALE" append ; NOTE: MYDATA.BIG_PRDSALE was successfully added to the "caspath" caslib as "big_PRDSALE". 61 quit ; NOTE: PROCEDURE CASUTIL used (Total process time): real time 49.58 seconds cpu time 5.05 seconds |
Log from simultaneous CAS session MYSESSION1 submitting APPEND
58 proc casutil ; NOTE: The UUID 'a20a246e-e0cc-da4d-8691-c0ff2a222dfd' is connected using session MYSESSION1. 59 load data=mydata.big_prdsale1 60 outcaslib="caspath" casout="big_PRDSALE" append ; NOTE: MYDATA.BIG_PRDSALE1 was successfully added to the "caspath" caslib as "big_PRDSALE". 61 quit ; NOTE: PROCEDURE CASUTIL used (Total process time): real time 1:30.33 cpu time 4.91 seconds |
When the data append process from MYSESSION1 was submitted alone (no simultaneous process), the execution time is around the same as for the first session MYSESSION. This also shows that when two simultaneous append processes were submitted against the CAS table, one was waiting for the other to finish. At one time, only one process was running the data APPEND action to the CAS table (no concurrent append).
Log from a lone CAS session MYSESSION1 submitting APPEND
58 proc casutil ; NOTE: The UUID 'a20a246e-e0cc-da4d-8691-c0ff2a222dfd' is connected using session MYSESSION1. 59 load data=mydata.big_prdsale1 60 outcaslib="caspath" casout="big_PRDSALE" append ; NOTE: MYDATA.BIG_PRDSALE1 was successfully added to the "caspath" caslib as "big_PRDSALE". 61 quit ; NOTE: PROCEDURE CASUTIL used (Total process time): real time 47.63 seconds cpu time 4.94 seconds |
The following log example describes two simultaneous CAS sessions submitting data updates on a CAS table. Both update processes were submitted to CAS in a span of a few seconds. Notice the execution time for the second CAS session MYSESSION1 is double the time it took the first session to update the same number of rows. The amount of memory used and the CAS_CACHE location also shows that both processes were running one after another in a serial fashion. While the update process was running, memory and CAS_CACHE space increased, which suggests that the update process makes copies of to-be-updated data rows/blocks. Once the update process is complete, the space usage in memory/CAS_CACHE returned to normal.
When the data UPDATE action from MYSESSION1 was submitted alone (no simultaneous process), the execution time is around the same as for the first CAS session.
Log from a simultaneous CAS session MYSESSION submitting UPDATE
58 proc cas ; 59 table.update / 60 set={ 61 {var="actual",value="22222"}, 62 {var="country",value="'FRANCE'"} 63 }, 64 table={ 65 caslib="caspath", 66 name="big_prdsale", 67 where="index in(10,20,30,40,50,60,70,80,90,100 )" 68 } 69 ; 70 quit ; NOTE: Active Session now MYSESSION. {tableName=BIG_PRDSALE,rowsUpdated=86400} NOTE: PROCEDURE CAS used (Total process time): real time 4:37.68 cpu time 0.05 seconds |
Log from a simultaneous CAS session MYSESSION1 submitting UPDATE
57 proc cas ; 58 table.update / 59 set={ 60 {var="actual",value="22222"}, 61 {var="country",value="'FRANCE'"} 62 }, 63 table={ 64 caslib="caspath", 65 name="big_prdsale", 66 where="index in(110,120,130,140,150,160,170,180,190,1100 )" 67 } 68 ; 69 quit ; NOTE: Active Session now MYSESSION1. {tableName=BIG_PRDSALE,rowsUpdated=86400} NOTE: PROCEDURE CAS used (Total process time): real time 8:56.38 cpu time 0.09 seconds |
The following memory usage snapshot from one of the CAS nodes describes the usage of memory before and during the CAS table update. Notice the values for “used” and “buff/cache” columns before and during the CAS table update.
Memory usage on a CAS node before starting a CAS table UPDATE
Memory usage on a CAS node during CAS table UDPATE
Summary
When simultaneous data append and data update requests are submitted against a global CAS table from two or more CAS sessions, they execute in a serial fashion (no concurrent process execution). To execute data updates on a CAS table, you need an additional overhead memory/CAS_CACHE space. While the CAS table is going through the data append or data update process, the CAS table is still accessible to rendering reports.