Placement prefs allow you to "spread" your replicas across nodes with certain tags, choosing to put the replicas as much "diverse" as possible.
Constraints will constrain (limit) the replicas to those nodes that match the constraint.
Image you have 4 servers in 2 datacenters (east, west) and some of the servers have an SSD drive, while others don't.
If you apply the following labels to the nodes:
node-1: datacenter=us-east, disk=ssd
node-2: datacenter=us-east, disk=ssd
node-3: datacenter=us-west, disk=sas
node-4: datacenter=us-west, disk=nl-sas
If you would deploy a service with 2 replicas and you want to provide geographic redundancy, you would start that service as follows:
docker service create \
--replicas 2 \
--name webserver \
--placement-pref 'spread=node.labels.datacenter' \
mywebservice:production
Docker Swarm would then try to "spread" the 2 replicas across both datacenters, so you'll end up with 1 replica on either node-1 or node-2, and the other replica on node-3 or node-4.
If you have a service (eg a reporting job) that does a lot of IOPS, you'll probably want to use your SSD equiped servers, so you'll place a constraint on the service:
docker service create \
--constraint 'node.labels.disk == ssd' \
myreporter:latest