|
| 1 | +.. Licensed to the Apache Software Foundation (ASF) under one |
| 2 | + or more contributor license agreements. See the NOTICE file |
| 3 | + distributed with this work for additional information |
| 4 | + regarding copyright ownership. The ASF licenses this file |
| 5 | + to you under the Apache License, Version 2.0 (the |
| 6 | + "License"); you may not use this file except in compliance |
| 7 | + with the License. You may obtain a copy of the License at |
| 8 | +
|
| 9 | + http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | +
|
| 11 | + Unless required by applicable law or agreed to in writing, |
| 12 | + software distributed under the License is distributed on an |
| 13 | + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 14 | + KIND, either express or implied. See the License for the |
| 15 | + specific language governing permissions and limitations |
| 16 | + under the License. |
| 17 | +
|
| 18 | +.. _admin-plugins-slice: |
| 19 | + |
| 20 | +Slice Plugin |
| 21 | +*************** |
| 22 | + |
| 23 | +This plugin takes client requests and breaks them up into |
| 24 | +successive aligned block requests. This supports both |
| 25 | +whole asset and single range requests. |
| 26 | + |
| 27 | +Purpose |
| 28 | +======= |
| 29 | + |
| 30 | +This slice plugin, along with the `cache_range_requests` |
| 31 | +plugin allows the following: |
| 32 | + |
| 33 | +- Fulfill arbitrary range requests by fetching a minimum |
| 34 | + number of cacheable aligned blocks to fulfill the request. |
| 35 | +- Breaks up very large assets into much smaller cache |
| 36 | + blocks that can be spread across multiple storage |
| 37 | + devices and within cache groups. |
| 38 | + |
| 39 | +Configuration |
| 40 | +============= |
| 41 | + |
| 42 | +This plugin is intended for use as a remap plugin and is |
| 43 | +configured in :file:`remap.config`. |
| 44 | + |
| 45 | +Or preferably per remap rule in :file:`remap.config`:: |
| 46 | + |
| 47 | + map http://ats/ http://parent/ @plugin=slice.so \ |
| 48 | + @plugin=cache_range_requests.so |
| 49 | + |
| 50 | +In this case, the plugin will use the default behaviour: |
| 51 | + |
| 52 | +- Fulfill whole file or range requests by requesting cacheable |
| 53 | + block aligned ranges from the parent and assemble them |
| 54 | + into client responses, either 200 or 206 depending on the |
| 55 | + client request. |
| 56 | +- Default block size is 1mb (1048576 bytes). |
| 57 | +- This plugin depends on the cache_range_requests plugin |
| 58 | + to perform actual parent fetching and block caching |
| 59 | + and If-* conditional header evaluations. |
| 60 | + |
| 61 | +Plugin Options |
| 62 | +-------------- |
| 63 | + |
| 64 | +The slice plugin supports the following options:: |
| 65 | + |
| 66 | + --blockbytes=<bytes> (optional) |
| 67 | + Default is 1m or 1048576 bytes |
| 68 | + -b <bytes> for short. |
| 69 | + Suffix k,m,g supported |
| 70 | + Limited to 32k and 32m inclusive. |
| 71 | + |
| 72 | + --blockbytes-test=<bytes> (optional) |
| 73 | + Suffix k,m,g supported |
| 74 | + -t <bytes> for short. |
| 75 | + Limited to any positive number. |
| 76 | + Ignored if --blockbytes provided. |
| 77 | + |
| 78 | + --remap-host=<loopback hostname> (optional) |
| 79 | + Uses effective url with given hostname for remapping. |
| 80 | + Requires setting up an intermediate loopback remap rule. |
| 81 | + -r for short |
| 82 | + |
| 83 | + --pace-errorlog=<seconds> (optional) |
| 84 | + Limit stitching error logs to every 'n' second(s) |
| 85 | + -p for short |
| 86 | + |
| 87 | + --disable-errorlog (optional) |
| 88 | + Disable writing block stitch errors to the error log. |
| 89 | + -d for short |
| 90 | + |
| 91 | + |
| 92 | +Examples:: |
| 93 | + |
| 94 | + @plugin=slice.so @pparam=--blockbytes=1000000 @plugin=cache_range_requests.so |
| 95 | + |
| 96 | +Or alternatively:: |
| 97 | + |
| 98 | + @plugin=slice.so @pparam=-b @pparam=1000000 @plugin=cache_range_requests.so |
| 99 | + |
| 100 | +Byte suffix examples:: |
| 101 | + |
| 102 | + slice.so --blockbytes=5m |
| 103 | + slice.so -b 512k |
| 104 | + slice.so --blockbytes=32m |
| 105 | + |
| 106 | +For testing and extreme purposes the parameter ``blockbytes-test`` may |
| 107 | +be used instead which is unchecked:: |
| 108 | + |
| 109 | + slice.so --blockbytes-test=1G |
| 110 | + slice.so -t 13 |
| 111 | + |
| 112 | +Because the slice plugin is susceptible to errors during block stitching |
| 113 | +extra logs related to stitching are written to ``diags.log``. Worst case |
| 114 | +an error log entry could be generated for every transaction. The |
| 115 | +following options are provided to help with log overrun:: |
| 116 | + |
| 117 | + slice.so --pace-errorlog=5 |
| 118 | + slice.so -p 1 |
| 119 | + slice.so --disable-errorlog |
| 120 | + |
| 121 | +After modifying :file:`remap.config`, restart or reload traffic server |
| 122 | +(sudo traffic_ctl config reload) or (sudo traffic_ctl server restart) |
| 123 | +to activate the new configuration values. |
| 124 | + |
| 125 | +Debug Options |
| 126 | +------------- |
| 127 | + |
| 128 | +While the current slice plugin is able to detect block consistency |
| 129 | +errors during the block stitching process, it can only abort the |
| 130 | +client connection. A CDN can only "fix" these by issuing an appropriate |
| 131 | +content revalidation. |
| 132 | + |
| 133 | +Under normal logging these slice block errors tend to show up as:: |
| 134 | + |
| 135 | + pscl value 0 |
| 136 | + crc value ERR_READ_ERROR |
| 137 | + |
| 138 | +By default more detailed stitching errors are written to ``diags.log``. |
| 139 | +Examples are as follows:: |
| 140 | + |
| 141 | +ERROR: [slice.cc: 288] logSliceError(): 1555705573.639 reason="Non 206 internal block response" uri="http://ats_ep/someasset.mp4" uas="curl" req_range="bytes=1000000-" norm_range="bytes 1000000-52428799/52428800" etag_exp="%221603934496%22" lm_exp="Fri, 19 Apr 2019 18:53:20 GMT" blk_range="21000000-21999999" status_got="206" cr_got="" etag_got="%221603934496%22" lm_got="" cc="no-store" via="" |
| 142 | + |
| 143 | +ERROR: [server.cc: 288] logSliceError(): 1572370000.219 reason="Mismatch block Etag" uri="http://ats_ep/someasset.mp4" uas="curl" req_range="bytes=1092779033-1096299354" norm_range="bytes 1092779033-1096299354/2147483648" etag_exp="%223719843648%22" lm_exp="Tue, 29 Oct 2019 14:40:00 GMT" blk_range="1095000000-1095999999" status_got="206" cr_got="bytes 1095000000-1095999999/2147483648" etag_got="%223719853648%22" lm_got="Tue, 29 Oct 2019 17:26:40 GMT" cc="max-age=10000" via="" |
| 144 | + |
| 145 | +Whether or how often these detailed log entries are written are |
| 146 | +configurable plugin options. |
| 147 | + |
| 148 | +Implementation Notes |
| 149 | +==================== |
| 150 | + |
| 151 | +This slice plugin is a stop gap plugin for handling special cases |
| 152 | +involving very large assets that may be range requested. Hopefully |
| 153 | +the slice plugin is deprecated in the future when partial object |
| 154 | +caching is finally implemented. |
| 155 | + |
| 156 | +Slice *ONLY* handles slicing up requests into blocks, it delegates |
| 157 | +actual caching and fetching to the cache_range_requests.so plugin. |
| 158 | + |
| 159 | +Plugin Function |
| 160 | +--------------- |
| 161 | + |
| 162 | +Below is a quick functional outline of how a request is served |
| 163 | +by a remap rule containing the Slice plugin with cache_range_requests: |
| 164 | + |
| 165 | +For each client request that comes in all remap plugins are run up |
| 166 | +until the slice plugin is hit. If the slice plugin *can* be run (ie: |
| 167 | +GET request) it will handle the request and STOP any further plugins |
| 168 | +from executing. |
| 169 | + |
| 170 | +At this point the request is sliced into 1 or more blocks by |
| 171 | +adding in range request headers ("Range: bytes="). A special |
| 172 | +header X-Slicer-Info header is added and the pristine URL is |
| 173 | +restored. |
| 174 | + |
| 175 | +For each of these blocks separate sequential TSHttpConnect(s) are made |
| 176 | +back into the front end of ATS and all of the remap plugins are rerun. |
| 177 | +Slice skips the remap due to presence of the X-Slicer-Info header and |
| 178 | +allows cache_range_requests.so to serve the slice block back to Slice |
| 179 | +either via cache OR parent request. |
| 180 | + |
| 181 | +Slice assembles a header based on the first slice block response and |
| 182 | +sends it to the client. If necessary it then skips over bytes in |
| 183 | +the first block and starts sending byte content, examining each |
| 184 | +block header and sends its bytes to the client until the client |
| 185 | +request is satisfied. |
| 186 | + |
| 187 | +Any extra bytes at the end of the last block are consumed by |
| 188 | +the the Slice plugin to allow cache_range_requests to finish |
| 189 | +the block fetch to ensure the block is cached. |
| 190 | + |
| 191 | +Important Notes |
| 192 | +=============== |
| 193 | + |
| 194 | +This plugin assumes that the content requested is cacheable. |
| 195 | + |
| 196 | +Any first block server response that is not a 206 is passed directly |
| 197 | +down to the client. If that response is a '200' only the first |
| 198 | +portion of the response is passed back and the transaction is closed. |
| 199 | + |
| 200 | +Only the first server response block is used to evaluate any "If-" |
| 201 | +conditional headers. Subsequent server slice block requests |
| 202 | +remove these headers. |
| 203 | + |
| 204 | +The only 416 response that this plugin handles itself is if the |
| 205 | +requested range is inside the last slice block but past the end of |
| 206 | +the asset contents. Other 416 responses are handled by the parent. |
| 207 | + |
| 208 | +If a client aborts mid transaction the current slice block continues to |
| 209 | +be read from the server until it is complete to ensure that the block |
| 210 | +is cached. |
| 211 | + |
| 212 | +Slice *always* makes ``blockbytes`` sized requests which are handled |
| 213 | +by cache_range_requests. The parent will trim those requests to |
| 214 | +account for the asset Content-Length so only the appropriate number |
| 215 | +of bytes are actually transferred and cached. |
| 216 | + |
| 217 | +Effective URL remap |
| 218 | +=================== |
| 219 | + |
| 220 | +By default the plugin restores the Pristine Url which reuses the same |
| 221 | +remap rule for each slice block. This is wasteful in that it reruns |
| 222 | +the previous remap rules, and those remap rules must be smart enough to |
| 223 | +check for the existence of any headers they may have created the first |
| 224 | +time they have were visited. |
| 225 | + |
| 226 | +To get around this the '--remap-host=<host>' or '-r <host>' option may |
| 227 | +be used. This requires an intermediate loopback remap to be defined which |
| 228 | +handles each slice block request. |
| 229 | + |
| 230 | +This works well with any remap rules that use the url_sig or uri_signing |
| 231 | +plugins. As the client remap rule is not caching any plugins that |
| 232 | +manipulate the cache key would need to go into the loopback to parent |
| 233 | +remap rule. |
| 234 | + |
| 235 | +NOTE: Requests NOT handled by the slice plugin (ie: HEAD requests) are |
| 236 | +handled as with a typical remap rule. GET requests intercepted by the |
| 237 | +slice plugin are virtually reissued into ATS and are proxied through |
| 238 | +another remap rule which must contain the ``cache_range_requests`` plugin |
| 239 | + |
| 240 | +Examples:: |
| 241 | + |
| 242 | + map http://ats/ http://parent/ @plugin=slice.so @pparam=--remap-host=loopback |
| 243 | + map http://loopback/ http://parent/ @plugin=cache_range_requests.so |
| 244 | + |
| 245 | +Alternatively:: |
| 246 | + |
| 247 | + map http://ats/ http://parent/ @plugin=slice.so @pparam=-r @pparam=loopback |
| 248 | + map http://loopback/ http://parent/ @plugin=cache_range_requests.so |
| 249 | + |
| 250 | +Current Limitations |
| 251 | +=================== |
| 252 | + |
| 253 | +Since the Slice plugin is written as an intercept handler it loses the |
| 254 | +ability to use normal state machine hooks and transaction states. This |
| 255 | +functionality is handled by using the ``cache_range_requests`` plugin |
| 256 | +to interact with ATS. |
0 commit comments