strimzi.io/type: kafka
strimzi.io/kind: cluster
Strimzi provides a way to run an Apache Kafka cluster on Kubernetes or OpenShift in various deployment configurations. This guide describes how to install and use Strimzi.
Apache Kafka is a popular platform for streaming data delivery and processing. For more details about Apache Kafka itself visit Apache Kafka website. The aim of Strimzi is to make it easy to run Apache Kafka on Kubernetes and OpenShift.
Strimzi consists of two main components:
Responsible for deploying and managing Apache Kafka clusters within a Kubernetes or OpenShift cluster
Responsible for managing Kafka topics within a Kafka cluster running within Kubernetes or OpenShift
A Kubernetes or OpenShift cluster is required to deploy Strimzi. Strimzi supports all kinds of clusters - from public and
private clouds down to local deployments intended for development purposes. This guide expects that a Kubernetes or
OpenShift cluster is available and the kubectl
or oc
command line tools are installed and configured to connect
to the running cluster.
When no existing Kubernetes or OpenShift cluster is available, Minikube
or Minishift
can be used to create a local
cluster. More details can be found in Appendix B, Installing Kubernetes and OpenShift cluster
In order to execute the commands in this guide, your Kubernetes/OpenShift user needs to have the rights to create and manage RBAC resources (Roles and Role Bindings).
Strimzi uses a component called the Cluster Controller to deploy and manage Kafka (including Zookeeper) and Kafka Connect clusters. The Cluster Controller is deployed as a process running inside your Kubernetes or OpenShift cluster. To deploy a Kafka cluster, a ConfigMap with the cluster configuration has to be created. Based on the information in that ConfigMap, the Cluster Controller will deploy a corresponding Kafka cluster. By default, the ConfigMap needs to be labeled with following labels:
strimzi.io/type: kafka
strimzi.io/kind: cluster
and contain the cluster configuration in a specific format. The ConfigMap format is described in Section 3.2, “Format of the cluster ConfigMap”.
Strimzi contains example YAML files which make deploying a Cluster Controller easier.
To deploy the Cluster Controller on Kubernetes, the following command should be executed:
kubectl create -f examples/install/cluster-controller
To verify whether the Cluster Controller has been deployed successfully, the Kubernetes Dashboard or the following command can be used:
kubectl describe all
To deploy the Cluster Controller on OpenShift, the following commands should be executed:
oc create -f examples/install/cluster-controller
oc create -f examples/templates/cluster-controller
To verify whether the Cluster Controller has been deployed successfully, the OpenShift console or the following command can be used:
oc describe all
Strimzi uses StatefulSets feature of Kubernetes/OpenShift to deploy Kafka brokers. With StatefulSets, the pods receive a unique name and network identity and that makes it easier to identify the individual Kafka broker pods and set their identity (broker ID). The deployment uses regular and headless services:
regular services can be used as bootstrap servers for Kafka clients
headless services are needed to have DNS resolve the pods IP addresses directly
As well as Kafka, Strimzi also installs a Zookeeper cluster and configures the Kafka brokers to connect to it. The Zookeeper cluster also uses StatefulSets.
Strimzi provides two flavors of Kafka broker deployment: ephemeral and persistent.
The ephemeral flavour is suitable only for development and testing purposes and not for production. The
ephemeral flavour uses emptyDir
volumes for storing broker information (Zookeeper) and topics/partitions
(Kafka). Using emptyDir
volume means that its content is strictly related to the pod life cycle (it is
deleted when the pod goes down). This makes the in-memory deployment well-suited to development and testing because
you don’t have to provide persistent volumes.
The persistent flavour uses PersistentVolumes to store Zookeeper and Kafka data. The PersistentVolume is acquired using a PersistentVolumeClaim – that makes it independent of the actual type of the PersistentVolume. For example, it can use HostPath volumes on Minikube or Amazon EBS volumes in Amazon AWS deployments without any changes in the YAML files. The PersistentVolumeClaim can use a StorageClass to trigger automatic volume provisioning.
To deploy a Kafka cluster, a ConfigMap with the cluster configuration has to be created. The ConfigMap should have the following labels:
strimzi.io/type: kafka
strimzi.io/kind: cluster
Example ConfigMaps and the details about the ConfigMap format are in Section 3.2.1, “Kafka”.
To deploy a Kafka broker on Kubernetes, the corresponding ConfigMap has to be created. To create the ephemeral cluster using the provided example ConfigMap, the following command should be executed:
kubectl apply -f examples/configmaps/cluster-controller/kafka-ephemeral.yaml
Another example ConfigMap is provided for persistent Kafka cluster. To deploy it, the following command should be run:
kubectl apply -f examples/configmaps/cluster-controller/kafka-persistent.yaml
For OpenShift, the Kafka broker is provided in the form of a template. The cluster can be deployed from the template either using the command line or using the OpenShift console. To create the ephemeral cluster, the following command should be executed:
oc new-app strimzi-ephemeral
Similarly, to deploy a persistent Kafka cluster the following command should be run:
oc new-app strimzi-persistent
The Cluster Controller can also deploy a Kafka Connect cluster which
can be used with either of the Kafka broker deployments described above. It is implemented as a Deployment with a
configurable number of workers. The default image currently contains only the Connectors distributed with Apache Kafka
Connect: FileStreamSinkConnector
and FileStreamSourceConnector
. The REST interface for managing the Kafka Connect
cluster is exposed internally within the Kubernetes/OpenShift cluster as kafka-connect
service on port 8083
.
Example ConfigMaps and the details about the ConfigMap format for deploying Kafka Connect can be found in Section 3.2.2, “Kafka Connect”.
To deploy Kafka Connect on Kubernetes, the corresponding ConfigMap has to be created. An example ConfigMap can be created using the following command:
kubectl apply -f examples/configmaps/cluster-controller/kafka-connect.yaml
On OpenShift, Kafka Connect is provided in the form of a template. It can be deployed from the template either using the command line or using the OpenShift console. To create a Kafka Connect cluster from the command line, the following command should be run:
oc new-app strimzi-connect
Strimzi Docker images for Kafka Connect contain, by default, only the FileStreamSinkConnector
and
FileStreamSourceConnector
connectors which are part of Apache Kafka.
To facilitate deployment with 3rd party connectors, Kafka Connect is configured to automatically load all
plugins/connectors which are present in the /opt/kafka/plugins
directory during startup. There are two ways of adding
custom plugins into this directory:
Using a custom Docker image
Using the OpenShift build system with the Strimzi S2I image
strimzi/kafka-connect
Strimzi provides its own Docker image for running Kafka Connect which can be found on Docker Hub as
strimzi/kafka-connect
. This image could be used as a base image for
building a new custom image with additional plugins. The following steps describe the process for creating such a custom image:
Create a new Dockerfile
which uses strimzi/kafka-connect
as the base image
FROM strimzi/kafka-connect:latest
USER root:root
COPY ./my-plugin/ /opt/kafka/plugins/
USER kafka:kafka
Build the Docker image and upload it to the appropriate Docker repository
Use the new Docker image in the Kafka Connect deployment:
On OpenShift, the template parameters IMAGE_REPO_NAME
, IMAGE_NAME
and IMAGE_TAG
can be changed to point to the
new image when the Kafka Connect cluster is being deployed
On Kubernetes, the Kafka Connect ConfigMap has to be modified to use the new image
OpenShift supports Builds which can be used together with
Source-to-Image (S2I) framework to create
new Docker images. OpenShift Build takes a builder image with S2I support together with source code and/or binaries
provided by the user and uses them to build a new Docker image. The newly created Docker Image will be stored in
OpenShift’s local Docker repository and can then be used in deployments. Strimzi provides a Kafka Connect builder
image strimzi/kafka-connect-s2i
with such S2I support. It takes user-provided
binaries (with plugins and connectors) and creates a new Kafka Connect image. This enhanced Kafka Connect image can be
used with our Kafka Connect deployment.
The S2I deployment is again provided as an OpenShift template. It can be deployed from the template either using the command line or using the OpenShift console. To create Kafka Connect S2I cluster from the command line, the following command should be run:
oc new-app strimzi-connect-s2i
Once the cluster is deployed, a new Build can be triggered from the command line:
A directory with Kafka Connect plugins has to be prepared first. For example:
$ tree ./my-plugins/
./my-plugins/
├── debezium-connector-mongodb
│ ├── bson-3.4.2.jar
│ ├── CHANGELOG.md
│ ├── CONTRIBUTE.md
│ ├── COPYRIGHT.txt
│ ├── debezium-connector-mongodb-0.7.1.jar
│ ├── debezium-core-0.7.1.jar
│ ├── LICENSE.txt
│ ├── mongodb-driver-3.4.2.jar
│ ├── mongodb-driver-core-3.4.2.jar
│ └── README.md
├── debezium-connector-mysql
│ ├── CHANGELOG.md
│ ├── CONTRIBUTE.md
│ ├── COPYRIGHT.txt
│ ├── debezium-connector-mysql-0.7.1.jar
│ ├── debezium-core-0.7.1.jar
│ ├── LICENSE.txt
│ ├── mysql-binlog-connector-java-0.13.0.jar
│ ├── mysql-connector-java-5.1.40.jar
│ ├── README.md
│ └── wkb-1.0.2.jar
└── debezium-connector-postgres
├── CHANGELOG.md
├── CONTRIBUTE.md
├── COPYRIGHT.txt
├── debezium-connector-postgres-0.7.1.jar
├── debezium-core-0.7.1.jar
├── LICENSE.txt
├── postgresql-42.0.0.jar
├── protobuf-java-2.6.1.jar
└── README.md
To start a new image build using the prepared directory, the following command has to be run:
oc start-build my-connect-cluster-connect --from-dir ./my-plugins/
The name of the build should be changed according to the cluster name of the deployed Kafka Connect cluster.
Once the build is finished, the new image will be used automatically by the Kafka Connect deployment.
Strimzi uses a component called the Topic Controller to manage topics in the Kafka cluster. The Topic Controller is deployed as a process running inside a Kubernetes/OpenShift cluster. To create a new Kafka topic, a ConfigMap with the related configuration (name, partitions, replication factor, …) has to be created. Based on the information in that ConfigMap, the Topic Controller will create a corresponding Kafka topic in the cluster.
Deleting a topic ConfigMap raises the deletion of the corresponding Kafka topic as well.
The Cluster Controller is able to deploy a Topic Controller, which can be configured in the cluster ConfigMap. Alternatively, it is possible to deploy a Topic Controller manually, rather than having it deployed by the Cluster Controller.
To deploy the Topic Controller through the Cluster Controller, its configuration needs to be provided in the cluster
ConfigMap in the topic-controller-config
field as a JSON string.
For more information on the JSON configuration format see Section <IP_ADDRESS>, “Topic controller”.
If you are not going to deploy the Kafka cluster using the Cluster Controller but you already have a Kafka cluster deployed on Kubernetes or OpenShift, it could be useful to deploy the Topic Controller using the provided YAML files. In that case you can still leverage on the Topic Controller features of managing Kafka topics through related ConfigMaps.
To deploy the Topic Controller on Kubernetes (not through the Cluster Controller), the following command should be executed:
kubectl create -f examples/install/topic-controller.yaml
To verify whether the Topic Controller has been deployed successfully, the Kubernetes Dashboard or the following command can be used:
kubectl describe all
To deploy the Topic Controller on OpenShift (not through the Cluster Controller), the following command should be executed:
oc create -f examples/install/topic-controller
To verify whether the Topic Controller has been deployed successfully, the OpenShift console or the following command can be used:
oc describe all
When the Topic Controller is deployed by the Cluster Controller it will be configured to watch for "topic ConfigMaps" which are those with the following labels:
strimzi.io/cluster: <cluster-name>
strimzi.io/kind: topic
When the Topic Controller is deployed manually the strimzi.io/cluster
label is not necessary.
The topic ConfigMap contains the topic configuration in a specific format. The ConfigMap format is described in Section 4.3, “Format of the ConfigMap”.
The cluster controller is in charge of deploying a Kafka cluster alongside a Zookeeper ensemble. As part of the Kafka cluster, it can also deploy the topic controller which provides operator-style topic management via ConfigMaps. The cluster controller is also able to deploy a Kafka Connect cluster which connects to an existing Kafka cluster. On OpenShift such a cluster can be deployed using the Source2Image feature, providing an easy way of including more connectors.
When the cluster controller is up, it starts to "watch" for ConfigMaps containing the Kafka or Kafka Connect
cluster configuration. Such ConfigMaps need to have a specific label which is, by default, strimzi.io/kind=cluster
(as described later) that can be changed through a corresponding environment variable.
When a new ConfigMap is created in the Kubernetes/OpenShift cluster, the controller gets the cluster configuration from
its data
section and starts creating a new Kafka or Kafka Connect cluster by creating the necessary Kubernetes/OpenShift
resources, such as StatefulSets, ConfigMaps, Services etc.
Every time the ConfigMap is updated by the user with some changes in the data
section, the controller performs corresponding
updates on the Kubernetes/OpenShift resources which make up the Kafka or Kafka Connect cluster. Resources are either patched
or deleted and then re-created in order to make the Kafka or Kafka Connect cluster reflect the state of the cluster ConfigMap.
This might cause a rolling update which might lead to service disruption.
Finally, when the ConfigMap is deleted, the controller starts to un-deploy the cluster deleting all the related Kubernetes/OpenShift resources.
Although the controller reacts to all notifications about the cluster ConfigMaps received from the Kubernetes/OpenShift cluster, if the controller is not running, or if a notification is not received for any reason, the ConfigMaps will get out of sync with the state of the running Kubernetes/OpenShift cluster.
In order to handle failovers properly, a periodic reconciliation process is executed by the cluster controller so that it can compare the state of the ConfigMaps with the current cluster deployment in order to have a consistent state across all of them.
The controller watches for ConfigMaps having the label strimzi.io/kind=cluster
in order to find and get
configuration for a Kafka or Kafka Connect cluster to deploy.
In order to distinguish which "type" of cluster to deploy, Kafka or Kafka Connect, the controller checks the
strimzi.io/type
label which can have one of the the following values :
kafka
: the ConfigMap provides configuration for a Kafka cluster (with Zookeeper ensemble) deployment
kafka-connect
: the ConfigMap provides configuration for a Kafka Connect cluster deployment
kafka-connect-s2i
: the ConfigMap provides configuration for a Kafka Connect cluster deployment using Build and Source2Image
features (works only with OpenShift)
Whatever other labels are applied to the ConfigMap will also be applied to the Kubernetes/OpenShift resources making up the Kafka or Kafka Connect cluster. This provides a convenient mechanism for those resource to be labelled in whatever way the user requires.
The data
section of such ConfigMaps contains different keys depending on the "type" of deployment as described in the
following sections.
In order to configure a Kafka cluster deployment, it’s possible to specify the following fields in the data
section of
the related ConfigMap :
kafka-nodes
: number of Kafka broker nodes. Default is 3
kafka-image
: the Docker image to use for the Kafka brokers.
Default is determined by the value of the
STRIMZI_DEFAULT_KAFKA_IMAGE
environment variable of the Cluster Controller.
kafka-healthcheck-delay
: the initial delay for the liveness and readiness probes for each Kafka broker node. Default is 15
kafka-healthcheck-timeout
: the timeout on the liveness and readiness probes for each Kafka broker node. Default is 5
zookeeper-nodes
: number of Zookeeper nodes
zookeeper-image
: the Docker image to use for the Zookeeper nodes.
Default is determined by the value of the
STRIMZI_DEFAULT_ZOOKEEPER_IMAGE
environment variable of the Cluster Controller.
zookeeper-healthcheck-delay
: the initial delay for the liveness and readiness probes for each Zookeeper node. Default is 15
zookeeper-healthcheck-timeout
: the timeout on the liveness and readiness probes for each Zookeeper node. Default is 5
KAFKA_DEFAULT_REPLICATION_FACTOR
: the default replication factors for automatically created topics. It sets the
default.replication.factor
property in the properties configuration file used by Kafka broker nodes on startup. Default is 3
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR
: the replication factor for the offsets topic. It sets the
offsets.topic.replication.factor
property in the properties configuration file used by Kafka broker nodes on startup. Default is 3
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR
: the replication factor for the transaction topic. It sets the
transaction.state.log.replication.factor
property in the properties configuration file used by Kafka broker nodes on startup. Default is 3
kafka-storage
: a JSON string representing the storage configuration for the Kafka broker nodes. See related section
zookeeper-storage
: a JSON string representing the storage configuration for the Zookeeper nodes. See related section
kafka-metrics-config
: a JSON string representing the JMX exporter configuration for exposing metrics from Kafka broker nodes.
Removing this field means having no metrics exposed.
zookeeper-metrics-config
: a JSON string representing the JMX exporter configuration for exposing metrics from Zookeeper nodes.
Removing this field means having no metrics exposed.
topic-controller-config
: a JSON string representing the topic controller configuration. See the Section <IP_ADDRESS>, “Topic controller”
documentation for further details. More info about the topic controller in the related Section 2.5, “Topic Controller” documentation page.
The following is an example of a ConfigMap for a Kafka cluster.
apiVersion: v1
kind: ConfigMap
metadata:
name: my-cluster
labels:
strimzi.io/kind: cluster
strimzi.io/type: kafka
data:
kafka-nodes: "3"
kafka-image: "strimzi/kafka:latest"
kafka-healthcheck-delay: "15"
kafka-healthcheck-timeout: "5"
zookeeper-nodes: "1"
zookeeper-image: "strimzi/zookeeper:latest"
zookeeper-healthcheck-delay: "15"
zookeeper-healthcheck-timeout: "5"
KAFKA_DEFAULT_REPLICATION_FACTOR: "3"
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "3"
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: "3"
kafka-storage: |-
{ "type": "ephemeral" }
zookeeper-storage: |-
{ "type": "ephemeral" }
kafka-metrics-config: |-
{
"lowercaseOutputName": true,
"rules": [
{
"pattern": "kafka.server<type=(.+), name=(.+)PerSec\\w*><>Count",
"name": "kafka_server_$1_$2_total"
},
{
"pattern": "kafka.server<type=(.+), name=(.+)PerSec\\w*, topic=(.+)><>Count",
"name": "kafka_server_$1_$2_total",
"labels":
{
"topic": "$3"
}
}
]
}
zookeeper-metrics-config: |-
{
"lowercaseOutputName": true
}
The resources created by the cluster controller into the Kubernetes/OpenShift cluster will be the following :
[cluster-name]-zookeeper
StatefulSet which is in charge to create the Zookeeper node pods
[cluster-name]-kafka
StatefulSet which is in charge to create the Kafka broker pods
[cluster-name]-zookeeper-headless
Service needed to have DNS resolve the Zookeeper pods IP addresses directly
[cluster-name]-kafka-headless
Service needed to have DNS resolve the Kafka broker pods IP addresses directly
[cluster-name]-zookeeper
Service used by Kafka brokers to connect to Zookeeper nodes as clients
[cluster-name]-kafka
Service can be used as bootstrap servers for Kafka clients
[cluster-name]-zookeeper-metrics-config
ConfigMap which contains the Zookeeper metrics configuration and mounted as
a volume by the Zookeeper node pods
[cluster-name]-kafka-metrics-config
ConfigMap which contains the Kafka metrics configuration and mounted as
a volume by the Kafka broker pods
Both Kafka and Zookeeper save data to files.
Strimzi allows to save such data in an "ephemeral" way (using emptyDir
) or in a "persistent-claim" way using persistent
volumes.
It’s possible to provide the storage configuration in the related ConfigMap using a JSON string as value for the
kafka-storage
and zookeeper-storage
fields.
|
Important
|
The kafka-storage and zookeeper-storage fields can’t be changed when the cluster is up.
|
The JSON representation has a mandatory type
field for specifying the type of storage to use ("ephemeral" or "persistent-claim").
The "ephemeral" storage is really simple to configure and the related JSON string has the following structure.
{ "type": "ephemeral" }
|
Warning
|
If the Zookeeper cluster is deployed using "ephemeral" storage, the Kafka brokers can have problems dealing with Zookeeper node restarts which could happen via updates in the cluster ConfigMap. |
In case of "persistent-claim" type the following fields can be provided as well :
size
: defines the size of the persistent volume claim (i.e 1Gi) - mandatory
class
: the Kubernetes/OpenShift storage class to use
for dynamic volume allocation - optional
selector
: allows to select a specific persistent volume to use. It contains a matchLabels
field which defines an
inner JSON object with key:value representing labels for selecting such a volume - optional
delete-claim
: boolean value which specifies if the persistent volume claim has to be deleted when the cluster is un-deployed.
Default is false
- optional
{ "type": "persistent-claim", "size": "1Gi" }
This example demonstrates use of a storage class.
{
"type": "persistent-claim",
"size": "1Gi",
"class": "my-storage-class"
}
Finally, a selector can be used in order to select a specific labeled persistent volume which provides some needed features (i.e. an SSD)
{
"type": "persistent-claim",
"size": "1Gi",
"selector":
{
"matchLabels":
{
"hdd-type": "ssd"
}
},
"delete-claim": true
}
When the "persistent-claim" is used, other than the resources already described in the Section 3.2.1, “Kafka” section, the following resources are generated :
data-[cluster-name]-kafka-[idx]
Persistent Volume Claim for the volume used for storing data for the Kafka broker pod [idx]
data-[cluster-name]-zookeeper-[idx]
Persistent Volume Claim for the volume used for storing data for the
Zookeeper node pod [idx]
Because Strimzi uses the [JMX exporter](https://github.com/prometheus/jmx_exporter) in order to expose metrics on each node, the JSON string used for metrics configuration in the cluster ConfigMap reflects the related JMX exporter configuration file. For this reason, you can find more information on how to use it in the corresponding GitHub repo.
For more information about using the metrics with Prometheus and Grafana, see Section <IP_ADDRESS>, “Metrics”
Alongside the Kafka cluster and the Zookeeper ensemble, the cluster controller can also deploy the topic controller.
In order to do that, the topic-controller-config
field has to be put into the data section of the cluster ConfigMap.
This field is a JSON string containing the topic controller configuration.
Without this field, the cluster controller doesn’t deploy the topic controller. It is still possible to deploy the topic
controller by creating appropriate Kubernetes/OpenShift resources.
The JSON representation of the 'topic-controller-config` has no mandatory fields and if the value is an empty object (just "{ }"), the cluster controller will deploy the topic controller with a default configuration.
The configurable fields are the following :
image
Docker image to use for the topic controller.
Default is determined by the value of the
STRIMZI_DEFAULT_TOPIC_CONTROLLER_IMAGE
environment variable of the Cluster Controller.
watchedNamespace
The Kubernetes namespace (OpenShift project) in which the topic controller watches for topic ConfigMaps. Default is the namespace where the topic controller is running
reconciliationIntervalMs
The interval between periodic reconciliations in milliseconds. Default is 900000 (15 minutes).
zookeeperSessionTimeoutMs
The Zookeeper session timeout in milliseconds. Default is 20000 milliseconds (20 seconds).
topicMetadataMaxAttempts
The number of attempts for getting topics metadata from Kafka. The time between each attempt
is defined as an exponential back-off. You might want to increase this value when topic creation could take more time due
to its larger size (i.e. many partitions/replicas). Default 6
.
{ "reconciliationIntervalMs": "900000", "zookeeperSessionTimeoutMs": "20000" }
More information about these configuration parameters in the related Section 2.5, “Topic Controller” documentation page.
In order to configure a Kafka Connect cluster deployment, it’s possible to specify the following fields in the data
section of
the related ConfigMap:
nodes
: number of Kafka Connect worker nodes. Default is 1
image
: the Docker image to use for the Kafka Connect workers.
Default is determined by the value of the
STRIMZI_DEFAULT_KAFKA_CONNECT_IMAGE
environment variable of the Cluster Controller.
If S2I is used (only on OpenShift), then it should be the related S2I image.
healthcheck-delay
: the initial delay for the liveness and readiness probes for each Kafka Connect worker node. Default is 60
healthcheck-timeout
: the timeout on the liveness and readiness probes for each Kafka Connect worker node. Default is 5
KAFKA_CONNECT_BOOTSTRAP_SERVERS
: a list of host/port pairs to use for establishing the initial connection to the Kafka cluster.
It sets the bootstrap.servers
property in the properties configuration file used by Kafka Connect worker nodes on startup.
Default is my-cluster-kafka:9092
KAFKA_CONNECT_GROUP_ID
: a unique string that identifies the Connect cluster group this worker belongs to.
It sets the group.id
property in the properties configuration file used by Kafka Connect worker nodes on startup.
Default is my-connect-cluster
KAFKA_CONNECT_KEY_CONVERTER
: converter class used to convert keys between Kafka Connect format and the serialized form
that is written to Kafka. It sets the key.converter
property in the properties configuration file used by Kafka Connect
worker nodes on startup. Default is org.apache.kafka.connect.json.JsonConverter
KAFKA_CONNECT_KEY_CONVERTER_SCHEMAS_ENABLE
: if Kafka Connect transformation on keys are with or without schemas.
It sets the key.converter.schemas.enable
property in the properties configuration file used by Kafka Connect worker nodes on startup.
Default is true
KAFKA_CONNECT_VALUE_CONVERTER
: converter class used to convert values between Kafka Connect format and the serialized form
that is written to Kafka. It sets the value.converter
property in the properties configuration file used by Kafka Connect
worker nodes on startup. Default is org.apache.kafka.connect.json.JsonConverter
KAFKA_CONNECT_VALUE_CONVERTER_SCHEMAS_ENABLE
: if Kafka Connect transformation on values are with or without schemas.
It sets the value.converter.schemas.enable
property in the properties configuration file used by Kafka Connect worker nodes on startup.
Default is true
KAFKA_CONNECT_CONFIG_STORAGE_REPLICATION_FACTOR
: replication factor used when creating the configuration storage topic.
It sets the config.storage.replication.factor
property in the properties configuration file used by Kafka Connect worker nodes on startup.
Default is 3
KAFKA_CONNECT_OFFSET_STORAGE_REPLICATION_FACTOR
: replication factor used when creating the offset storage topic.
It sets the offset.storage.replication.factor
property in the properties configuration file used by Kafka Connect worker nodes on startup.
Default is 3
KAFKA_CONNECT_STATUS_STORAGE_REPLICATION_FACTOR
: replication factor used when creating the status storage topic.
It sets the status.storage.replication.factor
property in the properties configuration file used by Kafka Connect worker nodes on startup.
Default is 3
The following is an example of cluster configuration ConfigMap is the following.
apiVersion: v1
kind: ConfigMap
metadata:
name: my-connect-cluster
labels:
strimzi.io/kind: cluster
strimzi.io/type: kafka-connect
data:
nodes: "1"
image: "strimzi/kafka-connect:latest"
healthcheck-delay: "60"
healthcheck-timeout: "5"
KAFKA_CONNECT_BOOTSTRAP_SERVERS: "my-cluster-kafka:9092"
KAFKA_CONNECT_GROUP_ID: "my-connect-cluster"
KAFKA_CONNECT_KEY_CONVERTER: "org.apache.kafka.connect.json.JsonConverter"
KAFKA_CONNECT_KEY_CONVERTER_SCHEMAS_ENABLE: "true"
KAFKA_CONNECT_VALUE_CONVERTER: "org.apache.kafka.connect.json.JsonConverter"
KAFKA_CONNECT_VALUE_CONVERTER_SCHEMAS_ENABLE: "true"
KAFKA_CONNECT_CONFIG_STORAGE_REPLICATION_FACTOR: "3"
KAFKA_CONNECT_OFFSET_STORAGE_REPLICATION_FACTOR: "3"
KAFKA_CONNECT_STATUS_STORAGE_REPLICATION_FACTOR: "3"
The resources created by the cluster controller into the Kubernetes/OpenShift cluster will be the following :
[connect-cluster-name]-connect Deployment which is in charge to create the Kafka Connect worker node pods
[connect-cluster-name]-connect Service which exposes the REST interface for managing the Kafka Connect cluster
For the controller to function it needs permission within the Kubernetes/OpenShift cluster to interact with the resources it manages (ConfigMaps, Pods, Deployments, StatefulSets, Services etc). Such permission is described in terms of Kubernetes/OpenShift role-based access controls.
The controller is best run using a ServiceAccount:
apiVersion: v1
kind: ServiceAccount
metadata:
name: strimzi-cluster-controller
labels:
app: strimzi
The Deployment of the controller then needs to specify this in the serviceAccountName
of its template
´s
spec
:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: strimzi-cluster-controller
spec:
replicas: 1
template:
metadata:
labels:
name: strimzi-cluster-controller
spec:
serviceAccountName: strimzi-cluster-controller
containers:
# etc ...
Note line 12, where the the strimzi-cluster-controller
ServiceAccount is specified as the serviceAccountName
.
The controller needs to operate using a Role that gives it access to the necessary resources
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: strimzi-cluster-controller-role
labels:
app: strimzi
rules:
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch
- create
- delete
- patch
- update
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
- delete
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- create
- delete
- patch
- update
- apiGroups:
- ""
resources:
- endpoints
verbs:
- get
- list
- watch
- apiGroups:
- "extensions"
resources:
- deployments
- deployments/scale
- replicasets
verbs:
- get
- list
- watch
- create
- delete
- patch
- update
- apiGroups:
- "apps"
resources:
- deployments
- deployments/scale
- deployments/status
- statefulsets
verbs:
- get
- list
- watch
- create
- delete
- patch
- update
- apiGroups:
- ""
resources:
- events
verbs:
- create
# OpenShift S2I requirements
- apiGroups:
- "extensions"
resources:
- replicationcontrollers
verbs:
- get
- list
- watch
- create
- delete
- patch
- update
- apiGroups:
- apps.openshift.io
resources:
- deploymentconfigs
- deploymentconfigs/scale
- deploymentconfigs/status
- deploymentconfigs/finalizers
verbs:
- get
- list
- watch
- create
- delete
- patch
- update
- apiGroups:
- build.openshift.io
resources:
- buildconfigs
- builds
verbs:
- create
- delete
- get
- list
- patch
- watch
- update
- apiGroups:
- image.openshift.io
resources:
- imagestreams
- imagestreams/status
verbs:
- create
- delete
- get
- list
- watch
- patch
- update
- apiGroups:
- ""
resources:
- replicationcontrollers
verbs:
- get
- list
- watch
- create
- delete
- patch
- update
Finally, the controller needs a RoleBinding which associates its Role with its ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: strimzi-cluster-controller-binding
labels:
app: strimzi
subjects:
- kind: ServiceAccount
name: strimzi-cluster-controller
roleRef:
kind: Role
name: strimzi-cluster-controller-role
apiGroup: rbac.authorization.k8s.io
The controller itself can be configured through the following environment variables.
STRIMZI_NAMESPACE
Required. A comma-separated list of namespaces that the controller should operate in. The Cluster Controller deployment might use the Kubernetes Downward API to set this automatically to the namespace the Cluster Controller is deployed in. See the example below:
env:
- name: STRIMZI_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
STRIMZI_FULL_RECONCILIATION_INTERVAL_MS
Optional, default: 120000 ms. The interval between periodic reconciliations, in milliseconds.
STRIMZI_OPERATION_TIMEOUT_MS
Optional, default: 60000 ms. The timeout for internal operations, in milliseconds. This value should be increased when using Strimzi on clusters where regular Kubernetes operations take longer than usual (because of slow downloading of Docker images, for example).
STRIMZI_DEFAULT_KAFKA_IMAGE
Optional, default strimzi/kafka:latest
.
The image name to use as a default when deploying Kafka, if
no image is specified as the kafka-image
in the Kafka cluster ConfigMap.
STRIMZI_DEFAULT_KAFKA_CONNECT_IMAGE
Optional, default strimzi/kafka-connect:latest
.
The image name to use as a default when deploying Kafka Connect, if
no image is specified as the image
in the
Kafka Connect cluster ConfigMap.
STRIMZI_DEFAULT_KAFKA_CONNECT_S2I_IMAGE
Optional, default strimzi/kafka-connect-s2i:latest
.
The image name to use as a default when deploying Kafka Connect S2I, if
no image is specified as the image
in the cluster ConfigMap.
STRIMZI_DEFAULT_TOPIC_CONTROLLER_IMAGE
Optional, default strimzi/topic-controller:latest
.
The image name to use as a default when deploying the topic controller, if
no image is specified as the image
in the topic controller config
of the Kafka cluster ConfigMap.
STRIMZI_DEFAULT_ZOOKEEPER_IMAGE
Optional, default strimzi/zookeeper:latest
.
The image name to use as a default when deploying Zookeeper, if
no image is specified as the zookeeper-image
in the Kafka cluster ConfigMap.
The STRIMZI_NAMESPACE
environment variable can be used to configure a single controller instance
to operate in multiple namespaces. For each namespace given, the controller will watch for cluster ConfigMaps
and perform periodic reconciliation. To be able to do this, the controller’s ServiceAccount needs
access to the necessary resources in those other namespaces. This can be done by creating an additional
RoleBinding in each of those namespaces, associating the controller’s ServiceAccount
(strimzi-cluster-controller
in the examples) with the controller’s
Role (strimzi-controller-role
in the examples).
Suppose, for example, that a controller deployed in namespace foo
needs to operate in namespace bar
.
The following RoleBinding would grant the necessary permissions:
bar
apiVersion: v1
kind: RoleBinding
metadata:
name: strimzi-cluster-controller-binding-bar
namespace: bar
labels:
app: strimzi
subjects:
- kind: ServiceAccount
name: strimzi-cluster-controller
namespace: foo
roleRef:
kind: Role
name: strimzi-cluster-controller-role
apiGroup: v1
The Topic Controller is in charge of managing topics in a Kafka cluster. The Topic Controller is deployed as a process running inside a Kubernetes/OpenShift cluster. It can be deployed through the Cluster Controller or "manually" through provided YAML files.
The role of the topic controller is to keep a set of Kubernetes ConfigMaps describing Kafka topics in-sync with corresponding Kafka topics.
Specifically:
if a config map is created, the controller will create the topic it describes
if a config map is deleted, the controller will delete the topic it describes
if a config map is changed, the controller will update the topic it describes
And also, in the other direction:
if a topic is created, the controller will create a config map describing it
if a topic is deleted, the controller will create the config map describing it
if a topic is changed, the controller will update the config map describing it
This is beneficial to a Kubernetes/OpenShift-centric style of deploying applications, because it allows you to declare a ConfigMap as part of your applications deployment and the controller will take care of creating the topic for you, so your application just needs to deal with producing and/or consuming from the necessary topics.
Should the topic be reconfigured, reassigned to different Kafka nodes etc, the ConfigMap will always be up to date.
A fundamental problem that the controller has to solve is that there is no single source of truth: Both the ConfigMap and the topic can be modified independently of the controller. Complicating this, the topic controller might not always be able to observe changes at each end in real time (the controller might be down etc).
To resolve this, the controller maintains its own private copy of the information about each topic. When a change happens either in the Kafka cluster, or in Kubernetes/OpenShift, it looks at both the state of the other system, and at its private copy in order to determine what needs to change to keep everything in sync. The same thing happens whenever the controller starts, and periodically while its running.
For example, suppose the topic controller is not running, and a ConfigMap "my-topic" gets created. When the controller starts it will lack a private copy of "my-topic", so it can infer that the ConfigMap has been created since it was last running. The controller will create the topic corresponding to "my-topic" and also store a private copy of the metadata for "my-topic".
The private copy allows the controller to cope with scenarios where the topic config gets changed both in Kafka and in Kubernetes/OpenShift, so long as the changes are not incompatible (e.g. both changing the same topic config key, but to different values). In the case of incompatible changes, the Kafka configuration wins, and the ConfigMap will be updated to reflect that. Defaulting to the Kafka configuration ensures that, in the worst case, data won’t be lost.
The private copy is held in the same ZooKeeper ensemble used by Kafka itself. This mitigates availability concerns, because if ZooKeeper is not running then Kafka itself cannot run, so the controller will be no less available than it would even if it was stateless.
Try to either always operate on ConfigMaps or always operate directly on topics.
When creating a ConfigMap:
Remember that you can’t easily change the name later.
Choose a name for the ConfigMap that reflects the name of the topic it describes.
Ideally the ConfigMap’s metadata.name
should be the same as its data.name
.
To do this, the topic name will have to be a valid Kubernetes resource name.
When creating a topic:
Remember that you can’t change the name later.
It’s best to use a name that is a valid Kubernetes resource name, otherwise the controller will have to sanitize the name when creating the corresponding ConfigMap.
By default, the controller only considers ConfigMaps having the label strimzi.io/kind=topic
,
but this is configurable via the STRIMZI_CONFIGMAP_LABELS
environment variable.
The data
of such ConfigMaps supports the following keys:
name
The name of the topic. Optional; if this is absent the name of the ConfigMap itself is used.
partitions
The number of partitions of the Kafka topic. This can be increased, but not decreased. Required.
replicas
The number of replicas of the Kafka topic. Required.
config
A string in JSON format representing the topic configuration. Optional, defaulting to the empty set.
Suppose you want to create a topic called "orders" with 10 partitions and 2 replicas.
You would first prepare a ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: orders
labels:
strimzi.io/kind: topic
data:
name: orders
partitions: "10"
replicas: "2"
Because the config
key is omitted from the data
the topic’s config will be empty, and thus default to the
Kafka broker default.
You would then create this ConfigMap in Kubernetes:
kubectl create -f orders-topic.yaml
Or in OpenShift:
oc create -f orders-topic.yaml
That’s it! The controller will create the topic "orders".
Suppose you later want to change the log segment retention time to 4 days,
you can update orders-topic.yaml
like this:
apiVersion: v1
kind: ConfigMap
metadata:
name: orders
labels:
strimzi.io/kind: topic
data:
name: orders
partitions: "10"
replicas: "2"
config: '{ "retention.ms":"345600000" }'
And use oc update -f
or kubectl update -f
to up update the ConfigMap
in OpenShift/Kubernetes.
You can’t change the data.name
key in a ConfigMap, because Kafka doesn’t support changing topic names.
You can’t decrease the data.partitions
, because Kafka doesn’t support this.
You should exercise caution in increasing data.partitions
for topics with keys, as it will change
how records are partitioned.
The controller is configured from environment variables:
STRIMZI_CONFIGMAP_LABELS
– The Kubernetes label selector used to identify ConfigMaps to be managed by the controller.
Default: strimzi.io/kind=topic
.
STRIMZI_ZOOKEEPER_SESSION_TIMEOUT_MS
– The Zookeeper session timeout, in milliseconds. For example 10000
. Default: 20000
(20 seconds).
STRIMZI_KAFKA_BOOTSTRAP_SERVERS
– The list of Kafka bootstrap servers. This variable is mandatory.
STRIMZI_ZOOKEEPER_CONNECT
– The Zookeeper connection information. This variable is mandatory.
STRIMZI_FULL_RECONCILIATION_INTERVAL_MS
– The interval between periodic reconciliations, in milliseconds.
STRIMZI_TOPIC_METADATA_MAX_ATTEMPTS
– The number of attempts for getting topics metadata from Kafka. The time between each attempt is defined as an exponential
back-off. You might want to increase this value when topic creation could take more time due to its larger size
(i.e. many partitions/replicas). Default 6
.
If the controller configuration needs to be changed the process must be killed and restarted. Since the controller is intended to execute within Kubernetes, this can be achieved by deleting the pod.
For each cluster, the Cluster Controller always executes only one operation at a time. The Cluster Controller uses locks to make sure that there are never two parallel operations running for the same cluster. In case an operation requires more time to complete, other operations will wait until it is completed and the lock is released.
Examples of cluster operations are cluster creation, rolling update, scale down or scale up etc.
If the wait for the lock takes too long, the operation times out and the following warning message will be printed to the log:
---
2018-03-04 17:09:24 WARNING AbstractClusterOperations:290 - Failed to acquire lock for kafka cluster lock::kafka::myproject::my-cluster
---
Depending on the exact configuration of STRIMZI_FULL_RECONCILIATION_INTERVAL_MS
and STRIMZI_OPERATION_TIMEOUT_MS
, this
warning message may appear regularly without indicating any problems. The operations which time out will be picked up by
the next periodic reconciliation. It will try to acquire the lock again and execute.
Should this message appear periodically even in situations when there should be no other operations running for a given cluster, it might indicate that due to some error the lock was not properly released. In such cases it is recommended to restart the cluster controller.
The easiest way to get started with Kubernetes or OpenShift is using the Minikube
, Minishift
or oc cluster up
utilities. This section provides basic guidance on how to use them. More details are provided on the websites of
the tools themselves.
In order to interact with a Kubernetes cluster the kubectl
utility needs to be installed.
The easiest way to get a running Kubernetes cluster is using Minikube
. Minikube
can be downloaded and installed
from the Kubernetes website. Depending on the number of brokers
you want to deploy inside the cluster and if you need Kafka Connect running as well, it could be worth running Minikube
at least with 4 GB of RAM instead of the default 2 GB.
Once installed, it can be started using:
minikube start --memory 4096
In order to interact with an OpenShift cluster, the oc
utility is needed.
An OpenShift cluster can be started in two different ways. The oc
utility can start a cluster locally using the
command:
oc cluster up
This command requires Docker to be installed. More information about this way can be found here.
Another option is to use Minishift
. MiniShift
is an OpenShift installation within a VM. It can be downloaded and
installed from the Minishift website. Depending on the number of brokers
you want to deploy inside the cluster and if you need Kafka Connect running as well, it could be worth running Minishift
at least with 4 GB of RAM instead of the default 2 GB.
Once installed, Minishift
can be started using the following command:
minishift start --memory 4GB
This section describes how to deploy a Prometheus server for scraping metrics from the Kafka cluster and showing them using a Grafana dashboard. The resources provided are examples to show how Kafka metrics can be stored in Prometheus: They are not a recommended configuration, and further support should be available from the Prometheus and Grafana communities.
When adding Prometheus and Grafana servers to an Apache Kafka deployment using minikube
or minishift
, the memory available to the virtual machine should be increased (to 4 GB of RAM, for example, instead of the default 2 GB). Information on how to increase the default amount of memory can be found in the following section Appendix B, Installing Kubernetes and OpenShift cluster.
The Prometheus server configuration uses a service discovery feature in order to discover the pods in the cluster from which it gets metrics.
In order to have this feature working, it’s necessary for the service account used for running the Prometheus service pod to have access to the API server to get the pod list. By default the service account prometheus-server
is used.
export NAMESPACE=[namespace]
oc login -u system:admin
oc create sa prometheus-server
oc adm policy add-cluster-role-to-user cluster-reader system:serviceaccount:${NAMESPACE}:prometheus-server
oc login -u developer
where [namespace]
is the namespace/project where the Apache Kafka cluster was deployed.
Finally, create the Prometheus service by running
oc create -f https://raw.githubusercontent.com/strimzi/strimzi/master/metrics/examples/prometheus/kubernetes.yaml
A Grafana server is necessary only to get a visualisation of the Prometheus metrics.
To deploy Grafana on OpenShift, the following commands should be executed:
oc create -f https://raw.githubusercontent.com/strimzi/strimzi/master/metrics/examples/grafana/kubernetes.yaml
The Prometheus server configuration uses a service discovery feature in order to discover the pods in the cluster from which it gets metrics.
If the RBAC is enabled in your Kubernetes deployment then in order to have this feature working, it’s necessary for the service account used for running the Prometheus service pod to have access to the API server to get the pod list. By default the service account prometheus-server
is used.
export NAMESPACE=[namespace]
kubectl create sa prometheus-server
kubectl create -f https://raw.githubusercontent.com/strimzi/strimzi/master/metrics/examples/prometheus/cluster-reader.yaml
kubectl create clusterrolebinding read-pods-binding --clusterrole=cluster-reader --serviceaccount=${NAMESPACE}:prometheus-server
where [namespace]
is the namespace/project where the Apache Kafka cluster was deployed.
Finally, create the Prometheus service by running
kubectl apply -f https://raw.githubusercontent.com/strimzi/strimzi/master/metrics/examples/prometheus/kubernetes.yaml
A Grafana server is necessary only to get a visualisation of Prometheus metrics.
To deploy Grafana on Kubernetes, the following commands should be executed:
kubectl apply -f https://raw.githubusercontent.com/strimzi/strimzi/master/metrics/examples/grafana/kubernetes.yaml
As an example, and in order to visualize the exported metrics in Grafana, the simple dashboard kafka-dashboard.json
file is provided.
The Prometheus data source, and the above dashboard, can be set up in Grafana by following these steps.
|
Note
|
If your cluster is running using minikube or minishift , you can use the port-forward command for forwarding traffic from the Grafana pod to the host. For example, you can access the Grafana UI by running oc port-forward grafana-1-fbl7s 3000:3000 (or using kubectl instead of oc ) and then pointing a browser to http://localhost:3000 .
|
Access to the Grafana UI using admin/admin
credentials.
Click on the "Add data source" button from the Grafana home in order to add Prometheus as data source.
Fill in the information about the Prometheus data source, specifying a name and "Prometheus" as type. In the URL field, the connection string to the Prometheus server (i.e. http://prometheus:9090
) should be specified. After "Add" is clicked, Grafana will test the connection to the data source.
From the top left menu, click on "Dashboards" and then "Import" to open the "Import Dashboard" window where the provided kafka-dashboard.json
file can be imported or its content pasted.
After importing the dashboard, the Grafana home should show with some initial metrics about CPU and JVM memory usage. When the Kafka cluster is used (creating topics and exchanging messages) the other metrics, like messages in and bytes in/out per topic, will be shown.


Randomly chosen items or values are important in many games. This sections shows how you can use Unity’s built-in random functions to implement some common game mechanics.
Picking an array element at random boils down to choosing a random integer between zero and the array’s maximum index value (which is equal to the length of the array minus one). This is easily done using the built-in Random.Range function:-
var element = myArray[Random.Range(0, myArray.Length)];
Note that Random.Range returns a value from a range that includes the first parameter but excludes the second, so using myArray.Length here gives the correct result.
Sometimes, you need to choose items at random but with some items more likely to be chosen than others. For example, an NPC may react in several different ways when it encounters a player:-
You can visualise these different outcomes as a paper strip divided into sections each of which occupies a fraction of the strip’s total length. The fraction occupied is equal to the probability of that outcome being chosen. Making the choice is equivalent to picking a random point along the strip’s length (say by throwing a dart) and then seeing which section it is in.
In the script, the paper strip is actually an array of floats that contain the different probabilities for the items in order. The random point is obtained by multiplying Random.value by the total of all the floats in the array (they need not add up to 1; the significant thing is the relative size of the different values). To find which array element the point is “in”, firstly check to see if it is less than the value in the first element. If so, then the first element is the one selected. Otherwise, subtract the first element’s value from the point value and compare that to the second element and so on until the correct element is found. In code, this would look something like the following:-
//JS
function Choose(probs: float[]) {
var total = 0;
for (elem in probs) {
total += elem;
}
var randomPoint = Random.value * total;
for (i = 0; i < probs.Length; i++) {
if (randomPoint < probs[i])
return i;
else
randomPoint -= probs[i];
}
return probs.Length - 1;
}
//C#
float Choose (float[] probs) {
float total = 0;
foreach (float elem in probs) {
total += elem;
}
float randomPoint = Random.value * total;
for (int i= 0; i < probs.Length; i++) {
if (randomPoint < probs[i]) {
return i;
}
else {
randomPoint -= probs[i];
}
}
return probs.Length - 1;
}
Note that the final return statement is necessary because Random.value can return a result of 1. In this case, the search will not find the random point anywhere. Changing the line
if (randomPoint < probs[i])
…to a less-than-or-equal test would avoid the extra return statement but would also allow an item to be chosen occasionally even when its probability is zero.
The array of floats method works well if you have discrete outcomes, but there are also situations where you want to produce a more continuous result - say, you want to randomize the number of gold pieces found in a treasure chest, and you want it to be possible to end up with any number between 1 and 100, but to make lower numbers more likely. Using the array-of-floats method to do this would require that you set up an array of 100 floats (i.e. sections on the paper strip) which is unwieldy; and if you aren’t limited to whole numbers but instead want any number in the range, it’s impossible to use that approach.
A better approach for continuous results is to use an AnimationCurve to transform a ‘raw’ random value into a ‘weighted’ one; by drawing different curve shapes, you can produce different weightings. The code is also simpler to write:
//JS
function CurveWeightedRandom(curve: AnimationCurve) {
return curve.Evaluate(Random.value);
}
//C#
float CurveWeightedRandom(AnimationCurve curve) {
return curve.Evaluate(Random.value);
}
A ‘raw’ random value between 0 and 1 is chosen by reading from Random.value. It is then passed to curve.Evaluate(), which treats it as a horizontal coordinate, and returns the corresponding vertical coordinate of the curve at that horizontal position. Shallow parts of the curve have a greater chance of being picked, while steeper parts have a lower chance of being picked.
Notice that these curves are not probability distribution curves like you might find in a guide to probability theory, but are more like inverse cumulative probability curves.
By defining a public AnimationCurve variable on one of your scripts, you will be able to see and edit the curve through the Inspector window visually, instead of needing to calculate values.
This technique produces floating-point numbers. If you want to calculate an integer result - for example, you want 82 gold pieces, rather than 82.1214 gold pieces - you can just pass the calculated value to a function like Mathf.RoundToInt().
A common game mechanic is to choose from a known set of items but have them arrive in random order. For example, a deck of cards is typically shuffled so they are not drawn in a predictable sequence. You can shuffle the items in an array by visiting each element and swapping it with another element at a random index in the array:-
//JS
function Shuffle(deck: int[]) {
for (i = 0; i < deck.Length; i++) {
var temp = deck[i];
var randomIndex = Random.Range(0, deck.Length);
deck[i] = deck[randomIndex];
deck[randomIndex] = temp;
}
}
//C#
void Shuffle (int[] deck) {
for (int i = 0; i < deck.Length; i++) {
int temp = deck[i];
int randomIndex = Random.Range(0, deck.Length);
deck[i] = deck[randomIndex];
deck[randomIndex] = temp;
}
}
A common task is to pick a number of items randomly from a set without picking the same one more than once. For example, you may want to generate a number of NPCs at random spawn points but be sure that only one NPC gets generated at each point. This can be done by iterating through the items in sequence, making a random decision for each as to whether or not it gets added to the chosen set. As each item is visited, the probability of its being chosen is equal to the number of items still needed divided by the number still left to choose from.
As an example, suppose that ten spawn points are available but only five must be chosen. The probability of the first item being chosen will be 5 / 10 or 0.5. If it is chosen then the probability for the second item will be 4 / 9 or 0.44 (ie, four items still needed, nine left to choose from). However, if the first was not chosen then the probability for the second will be 5 / 9 or 0.56 (ie, five still needed, nine left to choose from). This continues until the set contains the five items required. You could accomplish this in code as follows:-
//JS
var spawnPoints: Transform[];
function ChooseSet(numRequired: int) {
var result = new Transform[numRequired];
var numToChoose = numRequired;
for (numLeft = spawnPoints.Length; numLeft > 0; numLeft--) {
// Adding 0.0 is simply to cast the integers to float for the division.
var prob = (numToChoose + 0.0) / (numLeft + 0.0);
if (Random.value <= prob) {
numToChoose--;
result[numToChoose] = spawnPoints[numLeft - 1];
if (numToChoose == 0)
break;
}
}
return result;
}
//C#
Transform[] spawnPoints;
Transform[] ChooseSet (int numRequired) {
Transform[] result = new Transform[numRequired];
int numToChoose = numRequired;
for (int numLeft = spawnPoints.Length; numLeft > 0; numLeft--) {
float prob = (float)numToChoose/(float)numLeft;
if (Random.value <= prob) {
numToChoose--;
result[numToChoose] = spawnPoints[numLeft - 1];
if (numToChoose == 0) {
break;
}
}
}
return result;
}
Note that although the selection is random, items in the chosen set will be in the same order they had in the original array. If the items are to be used one at a time in sequence then the ordering can make them partly predictable, so it may be necessary to shuffle the array before use.
A random point in a cubic volume can be chosen by setting each component of a Vector3 to a value returned by Random.value:-
var randVec = Vector3(Random.value, Random.value, Random.value);
This gives a point inside a cube with sides one unit long. The cube can be scaled simply by multiplying the X, Y and Z components of the vector by the desired side lengths. If one of the axes is set to zero, the point will always lie within a single plane. For example, picking a random point on the “ground” is usually a matter of setting the X and Z components randomly and setting the Y component to zero.
When the volume is a sphere (ie, when you want a random point within a given radius from a point of origin), you can use Random.insideUnitSphere multiplied by the desired radius:-
var randWithinRadius = Random.insideUnitSphere * radius;
Note that if you set one of the resulting vector’s components to zero, you will not get a correct random point within a circle. Although the point is indeed random and lies within the right radius, the probability is heavily biased toward the edge of the circle and so points will be spread very unevenly. You should use Random.insideUnitCircle for this task instead:-
var randWithinCircle = Random.insideUnitCircle * radius;


FCS Teaching Topics: A Simple Heuristic to Calibrate Your Level of Expectaition in
Class
Bloom's Taxonomy Take-Aways
The Bloom's Taxonomy Pyramid - a quick reference to the levels.
Use the Bloom's Taxconomy Wheel to pick the best active verb to design your
questions and assessments.
What is Bloom's Taxonomy?
Bloom's Taxonomy helps educators - to create learning outcomes with
focussed terminology to reflect the difficulty of a task. It's extremely beneficial
for educators to be able to articulate the difficulty of tasks in their written
documentation and assessments. It encourages thinking about teaching and task
creation.
Bloom's Taxonomy helps students - to understand a clear direction for their
learning - which tasks require more thinking time and effort and the difficulty
level of specific tasks related to the course objectives.
Progression of Bloom's Taxonomy levels from lower level educational tasks growing in
complexity to those that require higher order critical thinking:
- remember
- understand
- apply
- analyse
- evaluate
- create
Where can I use this? In your course objectives, lesson objectives, teaching
strategies, learning activities and assessment tasks, and all educational
documentation to clearly indicate the level of cognitive application.
The visual representation of the taxonomy is usually in a pyramid
formation (although not exclusively). The hierarchical ordering of cognitive
skills starts with the easier cognitive tasks at the bottom and progresses in
difficulty with each section of the pyramid toward the top. To the right of each
stage of the pyramid is a brief explanation of the level with suggestions of
action terms to be used (Vanderbilt University, n.d.)
The Bloom's Taxonomy Colour Wheel - Terms and Activities
The colour wheel of Bloom's Taxonomy is especially helpful as it clearly
demonstrates what activities and action words fit into each one of the levels.
Keep in mind the order starts at Remembering (the easier tasks) and follows on
clockwise to Creating (the more challenging tasks) (John Hopkins, n.d.).
Writing Learning Objectives (Johns Hopkins University)
Johns Hopkins Whiting School of Engineering is just one higher educational institution that
uses
Bloom's Taxonomy to assist instructors in writing strong and relevant learning objectives. For helpful
tips and examples, click on this link:
References
Would you like to know more?
Drop by for a chat at The Academic Loop 239
Cell Number:<PHONE_NUMBER>
I'm looking forward to working with you - Stephanie Bernier


Schedule a Personal Tour
Come to Open House - 4.11.19 @ 7:30p
Request Info Via Mail (Address Required)
Name:
Email:
Phone Number:
Start date:
Not sure
Apr 15, 2019
May 15, 2019
Jun 15, 2019
Jul 15, 2019
Aug 15, 2019
Sep 15, 2019
Oct 15, 2019
Nov 15, 2019
Dec 15, 2019
Jan 15, 2020
Feb 15, 2020
Mar 15, 2020
Address:
city:
State:
Alabama
Alaska
Arizona
Arkansas
California
Colorado
Connecticut
Delaware
Florida
Georgia
Hawaii
Idaho
Illinois
Indiana
Iowa
Kansas
Kentucky
Louisiana
Maine
Maryland
Massachusetts
Michigan
Minnesota
Mississippi
Missouri
Montana
Nebraska
Nevada
New Hampshire
New Jersey
New Mexico
New York
North Carolina
North Dakota
Ohio
Oklahoma
Oregon
Pennsylvania
Puerto Rico
Rhode Island
South Carolina
South Dakota
Tennessee
Texas
Utah
Vermont
Virginia
Washington
Washington D.C.
West Virginia
Wisconsin
Wyoming
Zip Code:
I would like to be:
Not Sure
Audio Engineer
Music Producer
Video Producer
Songwriter
Performer
Entertainment Business
All of the above
How did you hear about us?
Web
Friend/Family
Other

I am not a Robot


Pirate (ARRR) is a cryptocurrency that solves the issue of financial privacy on the blockchain through forced anonymous transactions. Protect your wallet and transactions with Pirate’s completely anonymous network. With forced private transactions, your privacy cannot be compromised by another users’ activity on the network. If you wish to learn more, please join the official Pirate Discord at https://pirate.black/discord/ or message FishyGuts#5085, who will be happy to help out.
100 messages
Before 05-Dec-19 12:00 AM
Crypto Rich15-Nov-18 10:23 AM
I don't understand this Jar Tip. What do I do?
Thanks @Oszy What do I do to collect the tip?
@Flexatron I have referenced each of your articles so far in my weekly update videos.
Oszy15-Nov-18 10:26 AM
type in !arrrtip help in #tip-bot
you can withdraw
CryptoNinjaa15-Nov-18 10:27 AM
!arrrtip @Crypto Rich 1
Crypto Rich15-Nov-18 10:27 AM
ok
ARRR TipBotBOT15-Nov-18 10:27 AM
TipBot
@CryptoNinjaa (CryptoNinjaa#5350)
You tipped @Crypto Rich0.9999 ARRR
A network fee of 0.0001 ARRR was deducted from the amount.
This operation is pending. You will be notified when when it has finished.
Flexatron15-Nov-18 10:29 AM
Cool
Crypto Rich15-Nov-18 10:31 AM
Please post comments on the video. That helps it get found on the youtube algo
CryptoNinjaa15-Nov-18 10:38 AM
already called out a tokenpay maxamilist
Crypto Rich15-Nov-18 10:59 AM
@CryptoNinjaa I saw that. LOL I hold a fair amount of TPAY. Sold all my XVG last week, and now going to sell my XMR to get some KMD for ARRR!!!
Oszy15-Nov-18 11:00 AM
prices are now good to buy moarrr
jl777c15-Nov-18 11:01 AM
close to ATH hashrate
CryptoNinjaa15-Nov-18 11:01 AM
Cyrpto rich is an ARRR Maxamilist now lol.
Flexatron15-Nov-18 11:25 AM
Ath was 199.61 msol if I remember
Steve1015-Nov-18 11:59 AM
Is there a referral link to crex24 that Pirate is promoting?
jansako15-Nov-18 12:00 PM
pinned
Steve1015-Nov-18 12:00 PM
why didn't I think of that...too early in the morning. Thanks!
Flexatron15-Nov-18 12:27 PM
Signed up for crex in advance as well
BlockTech15-Nov-18 12:28 PM
Me to, now i'm just wondering if the first moove after listing will be up, or down ^^.
Flexatron15-Nov-18 12:36 PM
CMC listing will probs get some more buyers in
So up and down I think
passcombo.com 🏴☠🏴15-Nov-18 01:02 PM
if not BTC crash Arrr could 4x in price, now we can expect rather 2x maybe
reason - last few days DP traded daily mining, which means increasing buy orders slightly (new exchange, new buyers) would make the price much up
mrlynch15-Nov-18 01:08 PM
I believe crex is still testing. Don't deposit ARRR yet. I've sent 30 ARRR as a test and it hasn't credited yet. Been a few hours now
Europe’s leading retail broker for buying and selling cryptocurrencies. Trusted by over 900.000 users. | Founders: @TwinWinNerD, @eric_demuth & @christiant5r
Tweets
1105
Followers
10856
mrlynch15-Nov-18 01:10 PM
Nope
CryptoNinjaa15-Nov-18 01:12 PM
a few of the 2013/2014 guys will know TwinWinNerD
freakbros15-Nov-18 01:16 PM
What happened to him he used to be awesome
Or he still is but have not heard from him for very long time
Flexatron15-Nov-18 01:25 PM
Twinwinnerd
Hmm is he from NxT days?
Sounds very familiar
freakbros15-Nov-18 01:38 PM
Yes very good guy
Good trader
GatewayBOT15-Nov-18 01:56 PM
[dscrd-cz] <Paul> Hey I bought a gamer PC, do you know how to mine ARRR? Or is there a video from A - Z on how to set it up?
Paul15-Nov-18 02:00 PM
!arrrtip balance
ARRR TipBotBOT15-Nov-18 02:00 PM
TipBot
Please use #tip-bot to talk to TipBot.
GatewayBOT15-Nov-18 02:46 PM
[dscrd-cz] <BlockTech> @Paul You can find some info on : https://piratepool.io/getting_started .
But in case you don't know, $ARRR is no more worth it to mine with a GPU/CPU.
[dscrd-cz] <BlockTech> Only ASIC is worth mining ARRR since it reached 20Msol/s. (Actually around 120Msol/s now)
GatewayBOT15-Nov-18 03:03 PM
[dscrd-cz] <Paul> Thank you
Flexatron15-Nov-18 03:22 PM
Someone bought some. Kmd
FishyGuts15-Nov-18 03:33 PM
Crex says they have not received any of my deposits and then asked "If we can't look it up on the explorer, how do we know you're sending funds?
So Im not sure what's up there but I will advise as they continue to email.
I wish they would get in discord here to solve it
CryptoNinjaa15-Nov-18 03:34 PM
cant see how it cannot turn up tbh if they have given you the correct address.
jl777c15-Nov-18 03:36 PM
crex response indicates they have no clue about zaddr
3
LoPhatMelk15-Nov-18 03:37 PM
lovely
jl777c15-Nov-18 03:37 PM
you need to send them zcash payments API docs
CryptoNinjaa15-Nov-18 03:38 PM
send them the tx id for lols
Flexatron15-Nov-18 03:50 PM
Oh lord.
"sure we'll add your anon coin, no prob"
scubapanda15-Nov-18 04:01 PM
How did they create the receiving address?
Flexatron15-Nov-18 04:09 PM
I gave it to them
mrlynch15-Nov-18 04:16 PM
Lol
Flex, you getting our deposits?
!arrrtip @CryptoNinjaa 7.77
ARRR TipBotBOT15-Nov-18 04:19 PM
TipBot
@mrlynch (mrlynch#5735)
You tipped @CryptoNinjaa7.7699 ARRR
A network fee of 0.0001 ARRR was deducted from the amount.
This operation is pending. You will be notified when when it has finished.
CryptoNinjaa15-Nov-18 04:19 PM
@mrlynch thanks matey Arrr
mrlynch15-Nov-18 04:20 PM
Thank you for the crash course
1
FishyGuts15-Nov-18 04:30 PM
I’m not at my desk. Does anyone have the zcash docs for me to send them?
$ ./CostToMine.sh
Calculating with rental hash of 1 Million sol/s at 0.046 BTC or<PHONE_NUMBER>1 KMD per day
Mining an average of 2669.17478400 coins per day
Your cost per coin is .00001723 BTC or .10104831 KMD
You want to sell at .00001895 BTC or .11115314 KMD for a 10% markup
At that price, you will earn ~ .05058086 BTC or<PHONE_NUMBER>5 KMD
That's a total daily profit of ~ .00458086 BTC or 26.97153254 KMD
(edited)
Because, math
passcombo.com 🏴☠🏴15-Nov-18 04:39 PM
Crex24: @jl777c need to fix Pirates, they are clearly broken - no amounts or addresses on explorer!!!
the most broken chain @FishyGuts
PTYX15-Nov-18 04:40 PM
mrlynch15-Nov-18 04:40 PM
@ComputerGenie 👴👴👴 that's at a price of 0.046/1msol which is highly unlikely. I didn't get any hash power for hours at that price. Safest bid was around 0.051 to have constant hash
CryptoNinjaa15-Nov-18 04:40 PM
One question i get alot with full anon coins like pirate and xmr is how do you know the supply has not been inflated somehow? or do we just trust the algo ?
mrlynch15-Nov-18 04:41 PM
But yeah. I get your point
ComputerGenie 👴👴👴15-Nov-18 04:41 PM
@mrlynch that was a viable price 20 mins ago: more cost = less profit
mrlynch15-Nov-18 04:41 PM
Nice script though :D
That is true. My argument is that dumpers should have access to that script and stop selling for 0.000015
PTYX15-Nov-18 04:42 PM
@CryptoNinjaa there is no way of knowing unless someone does some deep analysis and detects some spooky action at a distance(edited)
mrlynch15-Nov-18 04:42 PM
As they are clearly at a loss
Might be better off just buying the coins
PTYX15-Nov-18 04:42 PM
i could be wrong
mrlynch15-Nov-18 04:43 PM
Less hassle
ComputerGenie 👴👴👴15-Nov-18 04:43 PM
My argument is that dumpers should have access to that script and stop selling for 0.000015
That's been my point since day 4 of being on dp
CryptoNinjaa15-Nov-18 04:43 PM
ok ptyx thank you - i trust the setup lol
mrlynch15-Nov-18 04:44 PM
Well, it's their cash that's being lost. I keep buying alongside mining
We can't fix stupit
2
CryptoNinjaa15-Nov-18 04:44 PM
hey dumb pers make my bread
mrlynch15-Nov-18 04:45 PM
I have a low tolerance for stupit though. Had 11 breaches i had to deal with in2 weeks because of dumb ppl
Good overtime though
ComputerGenie 👴👴👴15-Nov-18 04:46 PM
has 0 room to talk about stoopid and breaches
CryptoNinjaa15-Nov-18 04:46 PM
did somebody say beaches
mrlynch15-Nov-18 04:46 PM
Well it's my job
I am on one now @CryptoNinjaa
CryptoNinjaa15-Nov-18 04:46 PM
you in the canaries?
mrlynch15-Nov-18 04:47 PM
Aye
CryptoNinjaa15-Nov-18 04:47 PM
saw your post other day . ive just got back from tenerife myself well last sat
mrlynch15-Nov-18 04:47 PM
Good corporation tax 4% and 7% vat
At least until 2026
ComputerGenie 👴👴👴15-Nov-18 04:47 PM
@mrlynch I meant because of the fact that I gave myself a worm and it took my unencrypted wallet.dat along with all the KMD in it(edited)
mrlynch15-Nov-18 04:48 PM
Ouch
CryptoNinjaa15-Nov-18 04:48 PM
love the canaries great place. and yeah stuffs cheap as chips
mrlynch15-Nov-18 04:48 PM
Never test on your machine. If you were testing that is


BCN data strives to provide a data-centric view of life for people living in, affected by, or simply curious about Barcelona.
We’re a Catalan-American couple enjoying life in Barcelona.
Coloma Farre Lopez<EMAIL_ADDRESS>Joe Brew<EMAIL_ADDRESS>We’re on Instagram.
You can find us on twitter under the handle @bcndata.
Yep, facebook too.
This site's formatting was originally based on the "clean blog" template produced by Start Bootstrap (Iron Summit Media Strategies). We have modified it in accordance with the terms of the Apache 2.0 license. The original template can be found on github.


Who am I?
And I'm really excited to attend my first FOSSCOMM
Let's start with a story
A smart fella named Tim Berners Lee did something
That revolutionalized the way we communicate
And at first, it wasn't as ginormous as it is today
Computers ran code, and served it to the users that wanted to see the output
Who was going to pay for these computers?
The developers couldn't afford them
And the user didn't want to pay for each site that they would access
Sites were going to be free to access, granted that you had an internet connection
And the developers needed to make money in some other way
Which lead them towards the path of
But here's the thing
The internet isn't a TV
Because you have ways of delivering the right content to the right user
If you could analyze the content & data each user consumed
You could have a higher propability of those ads being clicked, since they were tailored
And therefore, you'd make more money
This was (and still is) a huge abuse of privacy
But don't worry!
Because it gets worse!
After attacks such as 9/11 happened
The government started to get even more demanding
What they wanted, was Backdoors
If you monitored every citizen of every country
You can (theoratically) prevent terroists
Certainly this power wasn't going to be abused.. Right?
Without telling anyone anything
Until whistleblowers spoke out
Such as Snowden, who exposed everything the NSA was doing
NSA was using big platforms
To gather more data from us
With the help of
Google, Facebook, Microsoft
Where are we now?
Should we just give up?
And let other people turn us and our privacy into money?
People fought back
And the IndieWeb was born
It's an alternative to the Big Data Companies
A way to rebel against Google, Facebook, Microsoft
It is diverse & powerful
That's not how it works.
You host platforms (programs) on a computer and serve that platform over the internet
Do you see the problem here?
My mom doesn't even know how to search on Google
Let alone run and operate a software stack
Not only powerful, but also
We can't let people miss out on it
We can help eachother
And help those who are tech illiterate
IndieWeb hosters
We are firm believers that you should be in control of your data
We offer encryption
And a variety of platforms
You can always check us out at cloud68.co
No. It is not
Everyone is tech literate
We have to find other ways to fight mass surveillance
I want to give all of you a big thank you
And if you have any questions, now's your chance
Don't be shy


Exact real-time pupil tracking is an important step in a live eye gaze. Since pupil centre is a base point’s reference, exact eye centre localization is essential for many applications.
In this project, we extract pupil eye features exactly within different intensity levels of eye images, mostly with localization of determined interest objects and where the human is looking, since it’s a digital world and digital transformation, everything is becoming virtual.
Hence this concept has a huge scope in e-learning, class room training, analyse human behaviour.
This project covers main process like Eye Ball and mentality & mood Recognition of Human Beings.
Feature extraction method named Kalman ﬁlter is used for gaze movement process.
Harr’s cascade classifier was used to first locate the eye’s area, and once found and support vector machine (SVM) for classification with the trained datasets.
We also include the state of emotions facial landmarks of the salient patches on face image using automated learning-free facial landmark detection technique.
In a virtual learning environment, learners can lose motivation and concentration easily, especially in a platform that is not tailored to their needs.
Our research is based on studying learner’s behavior on an online learning platform to create a system able to clustering learners based on their behavior, and adapting educational content to their needs.
Eye tracking is a set of techniques for recording eye movements.
This technology is used to measure eye positions and eye movement for research in psychology, psycholinguistics, ergonomics, e-learning and pre-testing of advertising.
This paper introduces the use of eye tracking technology to track and analyze the learners' behavior and emotion on e-learning platform like level of attention, stress, relaxation, problem solving and tiredness.
In e-learning, it is necessary to create more effective interaction between the educational content and learners.
In particular, increasing motivation by stimulating learners' interest is very important.
Users' eyes can be a significant source of information to analyze learner behavior.
What we look at, and how we do that, can be exploited to improve the learning process.
Eye movements provide an indication of learner interest and focus of attention.
They provide useful feedback to personalize learning interactions, and this can bring back some of the human functionality of a teacher.
With a study of eye movement, learners may be more motivated, and may find learning more fun.
From identification of where on the screen a user is looking, substantial value can be obtained.
The main aim of our project is developing a technique of eye detection and gaze estimation which is evolved from interest in a novel interface for laptop computers.
This interface would offers a user to control the computer through observing the features of interest and expresses action by blinking eyes.
This technology is beneficial for detection of fatigueness, surveillance, human computer interaction, advertisement etc.
For example: a driver are driving a car he could safely come to a stop should the driver experience a micro sleep.
Then the buzzer is ON and give instruction like a drive is fatigueness.
In human computer interface for a laptop the grinding technique are used and the indentification of pointer movement and we want to operate the laptop features in eye movement.
In this project the technique was used and carried out the gaze estimation of an eye.
Basically, eye detection technique is divided into three methods: a) Shape-based, b) Appearance-based; c) Hybrid shape and appearance-based.
In shape-based method, the eye shape such as eye edges, pupil, and eye corners are used as the features.
In appearance-based method, the photometric appearance of eye is used for detection.
Hybrid method combines both shape and appearance methods to exploit their advantages.
The goal for the project was to develop a new type of Human Computer Interaction system that subdues the problems that users have been facing with the current system. The project is implemented on a Li
nux system but could be implemented on a windows system by downloading some modules for python.
The algorithm applied is resistant to change in background image as it is not based on background image subtraction and is not programmed for a specific hand type; the algorithm used can process different hand types, recognizes no of fingers, and can carry out tasks as per requirement.
As it is stated within this paper, the main goals were reached.
The application is capable of the gesture recognition in real-time.
There are some limitations, which we still have to be overcome in future.
In today‘s world, the computers have become an important aspect of life and are used in various fields however, the systems and methods that we use to interact with computers are outdated and have various issues, which we will discuss a little later in this paper.
Hence, a very new field trying to overcome these issues has emerged namely HUMAN COMPUTER INTERACTIONS (HCI).
Although, computers have made numerous advancement in both fields of Software and Hardware, Still the basic way in which Humans interact with computers remains the same, using basic pointing device (mouse) and Keyboard or advanced Voice Recognition System, or maybe Natural Language processing in really advanced cases to make this communication more human and easy for us.
Our proposed project is the Hand gestures recognition system to replace the basic pointing devices used in computer systems to reduce the limitations that stay due to the legacy systems such as mouse and Touchpad.
The proposed system uses hand gesture, mostly no of fingers raised within the region of Interest to perform various operations such as Mouse move, Left click and Right click.
A static control board restrains the versatility of client and limits the capacity of the client like a remote can be lost, dropped or broken while, the physical nearness of client is required at sight of activity and that is a limitation of the user.
The proposed system can be used to control various soft panels like HMI systems, Robotics Systems, Telecommunication System, using hand gestures with help of programming by within python using pyautogui module to facilitate interaction within different functions of computer through the Camera to capture video frames.


Media Release
Home Media Release
Media Release
- "A linkage grant on activity and context recognition for behavior recommendation has been awarded" - UNSW Newsroom
- "Uni labs testing limits of quantum communications" - AFR
- "Boost program helps Raiz partner with UNSW to develop new customer technology" - NSW Industry
- "Raiz Invest partners with UNSW to advance machine learning" - IT Brief, Nikola News, BBIP, Australian FinTech
- “How cyber defence networks are being taught to self-heal” - UNSW News
- "Outstanding Women Researchers Recognised" - UoA News
- "Integrating The Physical And Digital Worlds" - UoA News


Such arrays waste memory and screw up data locality, wasting CPU cycles and caches.
The inspection is provided by Mike's IDEA Extensions.


--- sort_order: 13 tei_id: rdx_b6zxc.p.idp189205120 annotation_count: 1 images: small-thumbnail: https://readux.ecds.emory.edu/books/emory:b6zxc/pages/emory:h6stm/mini-thumbnail/ json: https://readux.ecds.emory.edu/books/emory:b6zxc/pages/emory:h6stm/info/ full: https://readux.ecds.emory.edu/books/emory:b6zxc/pages/emory:h6stm/fs/ page: https://readux.ecds.emory.edu/books/emory:b6zxc/pages/emory:h6stm/single-page/ thumbnail: https://readux.ecds.emory.edu/books/emory:b6zxc/pages/emory:h6stm/thumbnail/ title: Page 9 number: 9 permalink: "/pages/9/" ---


As I travel this journey for the perfect beer I want to be able to show off some of the tasty craft brews I have been able to create along the way.
My journey started in a Seattle Hop Shop. A well known shop that held weekly classes and provided me with some of the best hops and grains available in the area. After a couple years of brewing, I began to experiment with my own recipes, looking to make the perfect craft beer that I would be proud to share with friends, family and now you.
As I work towards my goal of becoming a well known brewer I am hoping that this site will bring attention to the craft I am proud of. Showing off my creations will keep me inspired to continue. Continue to make one of the best beverages loved around the globe!
This site was created to able to connect with other people interested in beer. My hope is that I will learn more about YOUR projects, and how we can collaborate together to find the juciest IPA, the milkiest stout and the god darn crispiest and coldest lager.
Hoping this site will give me more input on what you think about my products, I hope you reach out to me.
Be sure to shoot me an e-mail if you have any questions about collaborations, requests for guest taps or ideas for the future.


--- layout: default title: MAYDAY.US - News permalink: /news/ --- {% capture content %}
<EMAIL_ADDRESS><EMAIL_ADDRESS>MAYDAY PAC P.O. Box 75357 Washington, DC 20002


Mini Elastic Sift!
To query the API open a new terminal and run the command below with your query:
$> curl /_search?q=<FOO> -H 'Authorization: Api-Key <YOUR_KEY>'
Index stats:


E.g. Let us say you have the following configuration:
<config>
<service name="my-config">
<!-- lots of other stuff -->
</service>
</config>
You would need to put the following into your web.xml file:
<context-param> <param-name>oa4mp:oauth2.server.config.file</param-name> <param-value>/path/to/cfg.xml</param-value> </context-param>
<context-param>
<param-name>oa4mp:oauth2.server.config.name</param-name>
<param-value>my-config</param-value>
</context-param>
You may also have several configurations within a file and specify an alias or alternate name. This allows you to very easily switch configurations, keep old ones or have test configurations. To specify a configuration as an alias, you need to specify the name and alias tags:
<config> <service name="default" alias="new-config"/> <service name="new-config"> <!-- whole bunch of stuff for the actual configuration --> </service> <service name="mysql-5.0.2"> <!-- complete configuration here --> </service> </config>
In the example above, the service would be configured to always use "default" but the configuration is aliased to map this to "new-config". A typical use might be that the service is trying to migrate from mysql 5.0.2 and wants to preserve the old configuration so as to back out as needed. Again, you may have any number of aliases and aliases are transitive, so an alias can refer to another alias and so forth and these will be resolved down the chain.
<config> <service name="default" alias="new-config"/> <file include="/path/to/server-cfg.xml"/> </config>
<config> <service name="new-config"> <!-- whole bunch of stuff for the actual configuration --> </service> <service name="mysql-5.0.2"> <!-- complete configuration here --> </service> </config>
A really great use of this is specifying an administrative configuration. This lets you point to your main configuration as well as have other specialized configurations (such a file store for backing up a database, monitoring clients, etc.) You need only have a single server configuration file and refer to that.
Another use of configuration files is if you are running multiple versions of OA4MP. For instance, have a file for OAuth 1.0a-based configuration and one for OAuth2 - based ones. Then have a file that refers to these with aliases for the currently active configurations.


EBD - Easton Bible DIctionary
Gadarenes
GADARENES
"GADARENES "the inhabitants of Gadara, in Revised Version “Gerasenes”(
Mark 5:1
;
Luke 8:26, 37
). In
Matthew 8:28
they are called Gergesenes, Revised Version “Gadarenes.”
"GADARENES "the inhabitants of Gadara, in Revised Version “Gerasenes”(Mark 5:1; Luke 8:26, 37). In Matthew 8:28 they are called Gergesenes, Revised Version “Gadarenes.”


Home
About
Projects
Contact
Contact Me
Get in touch for any questions or to learn more about my projects.
Email
GitHub
LinkedIn


CrimPapers
Articles published on 13 July 2019
On 13 July 2019, 6 new articles were published in 5 journals.
Are Regional Crime Rates in India Natural?
A Longitudinal Study of Iranian Fans’ Cyberbullying: the Utility of Social Learning Theory by Seyyedeh Masoomeh (shamila) Shadmanfaat, Saeed Kabiri, Hayden Smith, John K. Cochran
Criminal Justice Contact Across Generations: Assessing the Intergenerational Labeling Hypothesis
Police Worldviews, Unconscious Bias, and Their Potential to Contribute to Racial and Ethnic Disparities in New York Police Department (nypd) Stops For Reason of “Furtive Movement” by Weston J. Morrow, John A. Shjarback
The Effect of School Discipline on Offending Across Time by Thomas J. Mowen, John J. Brent, John H. Boman
Affinity, Affiliation, and Guilt: Examining Between- and Within-Person Variability in Delinquent Peer Influence by Kyle J. Thomas, Timothy McCuddy


Market Update
Crypto Markets Continue to Drop, Bitcoin Briefly Slips Below $8,200
by Helen PartzAfter another sell-off earlier today, crypto markets have continued to fall, with Bitcoin (BTC) briefly dropping below the $8,200 threshold.
At the time of writing, 19 out of the top 20 coins by market cap are seeing significant losses. Texos (XTZ), the 17th altcoin by market cap, is resisting the bearish movement, still trading up around 1% over the past 24 hours at press time, according to Coin360.
Market visualization. Source: Coin360
After Bitcoin failed to reclaim $8,500 earlier today, its price has only continued to fall, dropping to as low as $8,104 per coin earlier on the day. At press time, Bitcoin has attempted a modest recovery and is trading at $8,215, down 4% over the past 24 hours.
New downturn to open up the potential for Bitcoin to return to $7,400
While Bitcoin is seeing a significant drop over the past seven days, down more than 5%, the major cryptocurrency is almost flat over the past 30 days at press time.
The fresh decline in the market is considered by some analysts to expose Bitcoin to a potential return to $7,400, as Cointelegraph reported today.
In contrast, other analysts suggested that Bitcoin’s recent trading into a falling wedge is typically a bullish pattern that has a success rate of breaking to the upside in around 68% of cases.
Last week, the CEO and co-founder of Distributed Lab claimed that Bitcoin price could “crash to zero” in the event of mass adoption by institutions.
Bitcoin 24-hour price chart. Source: Coin360
Ether (ETH), the second-largest cryptocurrency by market cap, is trading down 3.5% at $178. The top altcoin is seeing a similar percentage loss over the past seven days at press time.
Ether seven-day price chart. Source: Coin360
XRP, the third top cryptocurrency by market cap, has dropped 4.2% on the day to trade at 0.254. Over the past seven days, XRP is down 6.8%.
Ripple seven-day price chart. Source: Coin360
Total market capitalization amounts to $225 billion as of press time, as recorded by Coin360.
While industry experts are arguing about the near future of Bitcoin’s price, Fundstrat’s Tom Lee has recently reaffirmed his $25,000 prediction by 2022, claiming that such growth is “quite easy to achieve.”
Keep track of top crypto markets in real time here


Positioning
Hover me!
Hover me!
Hover me!
Hover me!
Hover me!
Hover me!
Hover me!
Hover me!
Length
Hover me!
I'm a medium tooltip.
I'm a large tooltip
I'm a Xlarge tooltip
My width will fit to element
Disabling animation
No animation!
Showing tooltips programatically
Always visible!
Customizing Tooltips
I am red!
I have big text!
I move a lot!
Glyphs and Icon Fonts
Hover me!
Hover me!
Hover me!


The landscape of JavaScript frameworks / libraries is changing fast. What started out as way to handle the DOM better through declarative data binding has evolved into a competitive niche with Google and Facebook pitching contrasting ideas and un expected collaborations – a Angular 2 is built on TypeScript. So with ES6 on the horizon this is how it looking:
- Angular 2.0
- Aurelia
- Ember.js
Now you are probably thinking where is React on that list. The guys at React say that it’s the V in MVC. But what does this mean for dynamic client UIs?
In the next couple of posts, I will explore this landscape with the intention of gaining a better understanding of where we may be heading. All I can say now is that will all these options, it’s a great time to be a client side developer.


| DOSE: |
0.5 g |
smoked |
Cannabis |
(plant material) |
I had tried weed before this occasion, but had failed to achieve a buzz before this particular time. Most smokers agree that your first high is the best one you will ever have...and I have to agree.
The night before my experience, I was at a party, and I approached one of my friends whose brother is a grower. I proceeded to ask him if i could buy a half gram of hydro, and he said yes, and it would be ten dollars. So i paid him his money and he went to break me off a half gram bud in the bathroom. He returned and dropped the resin soaked beauty into my hand. Thank you, I said, and I put it in the altoids tin in my pocket. Later on that night, I sat up at my desk and made a crude steamroller pipe out of a paper-towel role and the top to a salt and pepper shaker. I put this and the weed away in my closet until the proper time to use it.
The next day was Sunday and my mom anounced that she had to go to work at about 1:30 in the afternoon to finish a presentation, which I estimated would take her about 4 to 5 hours, so I knew I had plenty of time to use the weed.
When my mom left at approximatly 1:30, I took my home-made pipe, my weed, and a book of matches out to the garage. I held my hand over the end of the pipe, the 'carb', and struck and match on the garage floor with my other hand, the pipe was pressed against my lips, and I exhaled, then put the flame to the bud and sucked as hard as I could, hot smoke rushed into my lungs, and I held it in as long as I could, and when I exhaled, for about half a minute I felt as If I couldn't breath. I then felt fine, and finished off the rest of the bowl in one more big hit, and a series of small hits.
I got up, pipe in hand, and didn't feel too much. I then climbed the stairs from the garage into the house, and thats when it hit me. I got really, REALLY high very quickly, and I started to panick.  Then for no reason I picked up a book of Jim Carroll's poems, and I started to read. It relaxed me an amazing amount.But I decided to take a shower to remove the weed smell anyways. I found myself comparing every activity while high, to the same activity while sober. Everything is more interesting while high.
I got into the shower, and I swore I was listening to music from the radio but it was all in my head. The hot water felt so good against my body. When I got out of the shower I decided to do some homework and watch a movie(I have a bad habit of doing both at the same time).  I took out my biology assignment, and ended up just writing meaningless gibberish, its a bad idea to do schoolwork while high.
I then got very into the movie, even though I had seen it many times before. It was so much fun. I then realized I was really hungry, so I grabbed some poundcake in my fingers and went out and stood in the sun in my front yard, I felt so in tune with nature, and with the world, and so genuinly interested in everything. I was so happy. Right about then I also realized my high was starting to fade away, when I came in I glanced at the clock and it said 3:00. I read a book for the next fifteen minutes, and my imagination was racing and vivid. I sat in my chair in front of the TV again and felt sooo good, I was almost completely sober again at 3:45, my mom came home, and she didnt suspect a thing, and I got a little kick out of feeling all that forbidden joy and noone else in the world but myself knew it.
Since that first time, I have been a dedicated toker. I had been caught with my drug use my eighth grade year, a year before this experience. But before I had been using DXM and pharms. I later got caught again several times for using marijuana, but I think it is worth it. I have gone through many periods of using more heavily(every day, every other day etc.) and I still love weed. I think weed is a drug that is best used alone, but I have used it many times with others.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


Toggle navigation
Loading...
Home
Progress Overview
Knowledge Base
Groups
Logout
Select a lesson:
Progress Overview
Community Progress
Groups
Assign Randomly
Assign By Progress
Reset
Groups
Assign By Jigsaw
Reset
Progress Overview
Close
×
Progress Overview
Close
×
Please log in


[gecode-users] Gecode and Gist on Mac OS 10.6 "Snow Leopard"
Guido Tack
tack at ps.uni-sb.de
Fri Sep 4 13:50:29 CEST 2009
Hi everyone,
I've just upgraded my Mac to Snow Leopard and XCode 3.2 and ran a few
quick checks. It seems everything works well. Here's a couple of
notes:
The installer package from the Gecode download page apparently works
out of the box.
It seems that the installer package for Qt 4.5 has some issues on Snow
Leopard. As noted on
http://labs.trolltech.com/blogs/2009/08/31/qt-46-on-mac-os-106/
it may be necessary to uncheck the installation of Qt documentation.
If you build Gecode yourself, you have to know that XCode 3.2 uses gcc
4.2.1 by default. You therefore don't have to configure with
CC=gcc-4.2 CXX=g++-4.2 any longer. The new gcc is configured to
produce 64 bit code by default. This is fine unless you want to
compile Gist against the Qt binary package, which is 32 bit only. In
this case, simply configure with --with-architectures=i386.
If you encounter any other issues, let me know!
Cheers,
Guido
More information about the gecode-users
mailing list


Manchester United considering move for Reading striker Danny Loader
Manchester United are considering a move for Reading striker Danny Loader, but will face competition from a number of Premier League clubs that are also interested in the youngster.
The forward has represented England at every youth level from under-16 to under-20 and made his Reading debut at just 16-years-old.
Now 19-years-old, Loader has not quite made the impact with the Royals that was hoped for, scoring just one goal in 29 appearances since August 2017, although his record at youth level is excellent.
He is still considered a bright prospect and is out of contract at Reading in the summer after negotiations failed to produce a new deal.
Sky Sports reports that Man Utd are interested in snapping him up, but as are several other top flight sides.
Wolves came very close to signing Loader in the summer before a deadline day deal fell through, with Reading pulling the plug.
Advertisement Advertisement
‘Everyone knows a Premier League club tried to sign me in the transfer window, but it wasn’t to be,’ said Loader.
‘I’m very ambitious, my dream is to play on the biggest stage and you never know when these opportunities will come around again.’
Reading boss Mark Bowen said earlier this month that the club are still negotiating to try and keep Loader at the Madejski Stadium.
‘There are ongoing discussions between the club, him, his agent and his family,’ said Bowen.
‘He is very happy with his football and yes he wants more game time but he is a great professional, has a smile on his face and works hard. That’s all I can ask for.
‘He is a confident lad and has got a talent. At times he will be down but he has to be patient and he will get his chance.’


A website of MoveOn.org Civic Action.
MoveOn.org Civic Action is a 501(c)(4) organization which primarily focuses on nonpartisan education and advocacy on important national issues. MoveOn.org Political Action is a federal political committee which primarily helps members elect candidates who reflect our values through a variety of activities aimed at influencing the outcome of the next election. MoveOn.org Political Action and MoveOn.org Civic Action are separate organizations.


{{ define "content" }}
Oh snap! Our team of gophers could not find the web page you are looking for.
Homepage


{% from 'events/timetable/display/indico/_common.html' import render_speakers, render_references, render_description %} {% from 'attachments/_display.html' import render_attachments_folders %} {# Do not forget to update the conditions in the parent template when you add a new row in the details table. #}