Linked.Archi tactics extension Ontology for Architecture Decision and Architecture evaluation.
Linked.Archi
Linked.Archi tactics extension Ontology
In the case where two modules provide similar services, it may be cost-effective to implement the services just once in a more general (abstract) form. Any modification to the common service would then need to occur just in one place, • reducing modification cost.
All redundant components respond to events in parallel. • All in the same state. Response from only one component is used. Downtime: switching time to another up-to-date component (ms) Used in client-server config (database system) • Quick responses are important. Synchronization • All messages to any redundant component sent to all redundant components. Active redundancy (hot spare). This refers to a configuration where all of the nodes (active or redundant spare) in a protection group2 receive and process identical inputs in parallel, allowing the redundant spare(s) to maintain synchronous state with the active node(s). Because the redundant spare possesses an identical state to the active processor, it can take over from a failed component in a matter of milliseconds. The simple case of one active node and one redundant spare node is commonly referred to as 1+1 (“one plus one”) redundancy. Active redundancy can also be used for facilities protection, where active and standby network links are used to ensure highly available network connectivity.
Availability tactics are designed to enable a system to endure system faults so that a service being delivered by the system remains compliant with its specification. Goal of availability tactics • Keep faults from becoming failures or • bound the effects of the fault and make repair possible.
Place a limit on how much execution time is used to respond to an event. For iterative, data-dependent algorithms, limiting the number of iterations is a method for bounding execution times. The cost is usually a less accurate computation. If you adopt this tactic, you will need to assess its effect on accuracy and see if the result is “good enough.” This resource management tactic is frequently paired with the manage sampling rate tactic.
This controls the maximum number of queued arrivals and consequently the resources used to process the arrivals. If you adopt this tactic, you need to adopt a policy for what happens when the queues overflow and decide if not responding to lost events is acceptable. This tactic is frequently paired with the limit event response tactic.
checking conditions in a process or device, or validating assumptions made during the design.
This tactic operates on the demand side to produce smaller demand on the resources that will have to service the events.
Letting computers handle a change as much as possible will reduce the cost of making that change. The defer bindings are organized based on the system’s life cycle: • Compile time: o Component replacement (e.g. in a build script or makefile) o Compile-time parameterization o Aspect-Oriented programming • Deployment time: o configuration-time binding • Runtime: o Runtime registration o Dynamic lookup (e.g. for services) o Plug-ins o Publish-subscribe o Shared repositories o Polymorphism
maintains the most critical system functions in the presence of component failures, dropping less critical functions.
The purpose is to reduce the probability that a change to one module propagates to other modules • by introducing an explicit interface. The interface limits the ways in which external responsibilities can interact with the module. Interface should hide details of the module. Changes in the architecture: * An explicit interface S is added for element A * Coupling between A and Dependent elements is replaced with coupling between A and its interface S. * Strong coupling from A to its interface; low coupling from its interface to A.
allows the system to recover from faults by varying the granularity of the component(s) restarted and minimizing the level of service affected.
dealing with the exception by reporting it or handling it, potentially masking the fault by correcting the cause of the exception and retrying.
preventing system exceptions from occurring by masking a fault, or preventing it via smart pointers, abstract data types, wrappers
Heartbeat is a fault detection mechanism that employs a periodic message exchange between a system monitor and a process being monitored. • Comp. 1 emits a “heartbeat” message periodically • Comp. 2 listens for it • If heartbeat fails o Comp. 1 assumed failed o Fault correcting comp. 3 is notified Heartbeat can also carry data
// Each process has its own ID. var processId = "alpha"; var pubClient = require("redis").createClient(); setInterval(function () { pubClient.publish("heartbeat", processId); }), 100);
ignoring messages sent from a source when it is determined that those messages are spurious.
designing a component to handle more cases—faults—as part of its normal operation.
Improving the algorithms used in critical areas will decrease latency.
Faster processors, additional processors, additional memory, and faster networks all have the potential for reducing latency. Cost is usually a consideration in the choice of resources, but increasing the resources is definitely a tactic to reduce latency and in many cases is the cheapest way to get immediate improvement.
If responsibility A and B in a module do not serve the same purpose, • place them in different modules. The purpose of moving responsibilities from one module to another is to reduce the likelihood of side effects affecting other responsibilities in one module. If some responsibilities are not affected by changes, • they should be removed from the original module.
If requests can be processed in parallel, the blocked time can be reduced. Concurrency can be introduced by processing different streams of events on different threads or by creating additional threads to process different sets of activities. Once concurrency has been introduced, scheduling policies can be used to achieve the goals you find desirable. Different scheduling policies may maximize fairness (all requests get equal time), throughput (shortest time to finish first), or other goals. (See the sidebar.)
When discrete events arrive at the system (or element) too rapidly to be processed, then the events must be queued until they can be processed. Because these events are discrete, it is typically not desirable to “downsample” them. In such a case, you may choose to process events only up to a set maximum rate, thereby ensuring more predictable processing when the events are actually processed. This tactic could be triggered by a queue size or processor utilization measure exceeding some warning level. If you adopt this tactic and it is unacceptable to lose any events, then you must ensure that your queues are large enough to handle the worst case. If, on the other hand, you choose to drop events, then you need to choose a policy for handling this situation: Do you log the dropped events, or simply ignore them? Do you notify other systems, users, or administrators?
Multiple servers in a client-server pattern are replicas of computation. The purpose of replicas is to reduce the contention that would occur if all computations took place on a single server. A load balancer is a piece of software that assigns new work to one of the available duplicate servers; criteria for assignment vary but can be as simple as round-robin or assigning the next request to the least busy server.
Caching is a tactic that involves keeping copies of data (possibly one a subset of the other) on storage with different access speeds. The different access speeds may be inherent (memory versus secondary storage) or may be due to the necessity for network communication. Data replication involves keeping separate copies of the data to reduce the contention from multiple simultaneous accesses. Because the data being cached or replicated is usually a copy of existing data, keeping the copies consistent and synchronized becomes a responsibility that the system must assume. Another responsibility is to choose the data to be cached. Some caches operate by merely keeping copies of whatever was recently requested, but it is also possible to predict users’ future requests based on patterns of behavior, and begin the calculations or prefetches necessary to comply with those requests before the user has made them.
This tactic operates on the response side to make the resources at hand work more effectively in handling the demands put to them.
If it is possible to reduce the sampling frequency at which a stream of environmental data is captured, then demand can be reduced, typically with some attendant loss of fidelity. This is common in signal processing systems where, for example, different codecs can be chosen with different sampling rates and data formats. This design choice is made to maintain predictable levels of latency; you must decide whether having a lower fidelity but consistent stream of data is preferable to losing packets of data.
A component that is used to monitor the state of health of various other parts of the system (processors, I/O, memory, etc) • Detect failure or congestion in the network Note that this Tactic makes use of a Monitor Element. This will impact the Model, Pattern and Reference Architecture used.
used to enable graceful degradation of high-availability systems. Non-stop forwarding (NSF) is a concept that originated in router design. In this design functionality is split into two parts: supervisory, or control plane (which manages connectivity and routing information), and data plane (which does the actual work of routing packets from sender to receiver). If a router experiences the failure of an active supervisor, it can continue forwarding packets along known routes—with neighboring routers—while the routing protocol information is recovered and validated. When the control plane is restarted, it implements what is sometimes called “graceful restart,” incrementally rebuilding its routing protocol database even as the data plane continues to operate.
Primary component • responds to events • informs standby components of state updates they must make Fault occurs: • System checks if backup sufficiently fresh before resuming services Often used in control systems Periodical switchovers increase availability Passive redundancy (warm spare). This refers to a configuration where only the active members of the protection group process input traffic; one of their duties is to provide the redundant spare(s) with periodic state updates. Because the state maintained by the redundant spares is only loosely coupled with that of the active node(s) in the protection group (with the looseness of the coupling being a function of the checkpointing mechanism employed between active and redundant nodes), the redundant nodes are referred to as warm spares. Depending on a system’s availability requirements, passive redundancy provides a solution that achieves a balance between the more highly available but more compute-intensive (and expensive) active redundancy tactic and the less available but significantly less complex cold spare tactic (which is also significantly cheaper). (For an example of implementing passive redundancy.
Ping/echo is an asynchronous request/response message pair exchanged between nodes. • Comp. 1 (often a system monitor) issues a “ping” to comp. 2 • Comp. 1 expects an “echo” from comp. 2 • Answer within predefined time threshold Usable for a group of components • Mutually responsible for one task Usable for client/server • Tests the server and the communication path Standard implementations are available for nodes interconnected via IP.
monitor the state of health of a process to ensure that the system is operating within nominal parameters; take corrective action when conditions are detected that are predictive of likely future faults
They are based on a variety of combinations of retrying a computation or introducing redundancy.
If not all events are equally important, you can impose a priority scheme that ranks events according to how important it is to service them. If there are not enough resources available to service them when they arise, low-priority events might be ignored. Ignoring events consumes minimal resources (including time), and thus increases performance compared to a system that services all events all the time. For example, a building management system may raise a variety of alarms. Life-threatening alarms such as a fire alarm should be given higher priority than informational alarms such as a room is too cold.
reassigning responsibilities to the resources left functioning, while maintaining as much functionality as possible.
The use of intermediaries (so important for modifiability) increases the resources consumed in processing an event stream, and so removing them improves latency. This is a classic modifiability/performance tradeoff. Separation of concerns, another linchpin of modifiability, can also increase the processing overhead necessary to service an event if it leads to an event being serviced by a chain of components rather than a single component. The context switching and intercomponent communication costs add up, especially when the components are on different nodes on a network. A strategy for reducing computational overhead is to co-locate resources. Co-location may mean hosting cooperating components on the same processor to avoid the time delay of network communication; it may mean putting the resources in the same runtime software component to avoid even the expense of a subroutine call . A special case of reducing computational overhead is to perform a periodic cleanup of resources that have become inefficient. For example, hash tables and virtual memory maps may require recalculation and reinitialization. Another common strategy is to execute single-threaded servers (for simplicity and avoiding contention) and split workload across them.
Refactor is a tactic undertaken when two modules are affected by the same change because they are duplicates of each other. • Common responsibilities (and the code that implements them) are “factor out” of the modules. • By co-locating common responsibilities, the architect can reduce coupling.
It is where a failed component is reintroduced after it has been corrected.
This tactic refers to temporarily placing a system component in an out-of-service state for the purpose of mitigating potential system failures. One example involves taking a component of a system out of service and resetting the component in order to scrub latent faults (such as memory leaks, fragmentation, or soft errors in an unprotected cache) before the accumulation of faults affects service (resulting in system failure). Another term for this tactic is software rejuvenation.
Restrict dependencies is a tactic that restricts the modules that a given module interacts with or depends on. It is achieved by • restricting a module’s visibility; • authorization. Examples: layered architecture, wrapper
where a failure is transient retrying the operation may lead to success
permits the system to revert to a previous known good state upon the detection of a failure.
checks the validity or reasonableness of a component’s operations or outputs; typically based on a knowledge of the internal design, the state of the system, or the nature of the information under scrutiny.
Whenever there is contention for a resource, the resource must be scheduled. Processors are scheduled, buffers are scheduled, and networks are scheduled. Your goal is to understand the characteristics of each resource’s use and choose the scheduling strategy that is compatible with it.
Security is a measure of the system’s ability to protect data and information from unauthorized access while still providing access to people and systems that are authorized. An action taken against a computer system with the intention of doing harm is called an attack and can take a number of forms. It may be an unauthorized attempt to access data or services or to modify data, or it may be intended to deny services to legitimate users.
procedure for a component to test itself for correct operation
Previously failed component may be run in “shadow” mode. • For a while • To make sure it mimics the behavior of the working components • Before restoring it to service
in-service upgrades to executable code images in a non-service-affecting manner
Standby spare computing platform configured to replace many different failed components • Must be rebooted to appropriate SW config • Have its state initialized when failure occurs Checkpoint of system state and state changes to persistent device periodically. Downtime: minutes • Suited for systems having only high-reliability instead of high-availability. Spare (cold spare). Cold sparing refers to a configuration where the redundant spares of a protection group remain out of service until a fail-over occurs, at which point a power-on-reset procedure is initiated on the redundant spare prior to its being placed in service. Due to its poor recovery performance, cold sparing is better suited for systems having only high-reliability (MTBF) requirements as opposed to those also having high-availability requirements.
Refining the module into several smaller modules should reduce the average cost of future changes. • High capability → high cost of modification Criterion for splitting: • Children module can be modified independently
Partner to passive and active redundancy • Restored component upgrades its state before return to service. • Active redundancy: checksum, MD5… • Passive redundancy: checkpoint
used to detect incorrect sequences of events, primarily in distributed message-passing systems.
sequential steps bundled together, s.t. the whole bundle can be undone at once • Atomic, consistent, isolated, and durable (ACID property) Example: TwoPhase commit • Prevent race condition
An intermediary breaks a dependency. • Carrying out B requires carrying out A first The type of intermediary depends on the type of dependency. • A is a data producer and B is a data consumer: use a Publisher-Subscriber intermediary. • In a shared data repository, separates readers from writers.
Triple modular redundancy (TMR) employs three components that do the same thing. • Each component receives identical inputs, and forwards their output to voting logic. When an inconsistency occurs, the voter reports a fault. • It must also decide what output to use (majority voting or average of outputs). Replication • Components are exact clones of each other. Functional redundancy • It is intended to address the issue of common-mode failures (design or implementation faults). • Components are diversely designed and implemented with the same output given the same input. Analytic redundancy • It allows diversity among the components’ inputs and outputs. • It is intended to tolerate specification errors by using separate requirement specifications